about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-12-10 01:43:40 +0000
committerUlrich Drepper <drepper@redhat.com>2007-12-10 01:43:40 +0000
commitb4354cf42008f12cac246759b64db0439a82ce67 (patch)
treec5f15a5aae3d23cbc4a603bf07532aa85959c404
parent87520cccf6207f0a3525b5a5d5dc2ffd80b3d416 (diff)
downloadglibc-b4354cf42008f12cac246759b64db0439a82ce67.tar.gz
glibc-b4354cf42008f12cac246759b64db0439a82ce67.tar.xz
glibc-b4354cf42008f12cac246759b64db0439a82ce67.zip
[BZ #5424, BZ #5428, BZ #5451]
2007-12-08  Ulrich Drepper  <drepper@redhat.com>
	[BZ #5424]
	* stdio-common/vfprintf.c: Do not overflow when adding to done.
	* stdio-common/Makefile (tests): Add bug22.
	* stdio-common/bug22.c: New file.

	[BZ #5451]
	* time/getdate.c: Fix filling in default values.
	* time/bug-getdate1.c: New file.
	* time/Makefile: Add rules to build and run bug-getdate1.

	* iconvdata/ebcdic-is-friss.c: Use 8bit-gap instead of 8bit-generic.
	* iconvdata/ebcdic-es.c: Likewise.
	* iconvdata/ebcdic-es-a.c: Likewise.
	* iconvdata/ebcdic-uk.c: Likewise.
	* iconvdata/iso8859-16.c: Likewise.
	* iconvdata/viscii.c: Likewise.
	* iconvdata/iso8859-9e.c: Likewise.
	* iconvdata/Makefile: Adjust appropriately.

	[BZ #5428]
	* wcsmbs/wchar.h: Unconditionally undefine __need_mbstate and
	__need_wint_t.

	* iconvdata/gconv-modules: Likewise.
-rw-r--r--ChangeLog26
-rw-r--r--NEWS4
-rw-r--r--iconvdata/Makefile16
-rw-r--r--iconvdata/ebcdic-es-a.c8
-rw-r--r--iconvdata/ebcdic-es.c8
-rw-r--r--iconvdata/ebcdic-is-friss.c8
-rw-r--r--iconvdata/ebcdic-uk.c8
-rw-r--r--iconvdata/gconv-modules7
-rw-r--r--iconvdata/iso8859-16.c9
-rw-r--r--iconvdata/iso8859-9e.c7
-rw-r--r--iconvdata/viscii.c9
-rw-r--r--stdio-common/Makefile2
-rw-r--r--stdio-common/bug22.c32
-rw-r--r--stdio-common/vfprintf.c32
-rw-r--r--time/Makefile4
-rw-r--r--time/bug-getdate1.c146
-rw-r--r--time/getdate.c21
-rw-r--r--wcsmbs/wchar.h5
18 files changed, 296 insertions, 56 deletions
diff --git a/ChangeLog b/ChangeLog
index ff97ce94d6..560a6e6cc1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,35 @@
+2007-12-08  Ulrich Drepper  <drepper@redhat.com>
+
+	[BZ #5424]
+	* stdio-common/vfprintf.c: Do not overflow when adding to done.
+	* stdio-common/Makefile (tests): Add bug22.
+	* stdio-common/bug22.c: New file.
+
+	[BZ #5451]
+	* time/getdate.c: Fix filling in default values.
+	* time/bug-getdate1.c: New file.
+	* time/Makefile: Add rules to build and run bug-getdate1.
+
+	* iconvdata/ebcdic-is-friss.c: Use 8bit-gap instead of 8bit-generic.
+	* iconvdata/ebcdic-es.c: Likewise.
+	* iconvdata/ebcdic-es-a.c: Likewise.
+	* iconvdata/ebcdic-uk.c: Likewise.
+	* iconvdata/iso8859-16.c: Likewise.
+	* iconvdata/viscii.c: Likewise.
+	* iconvdata/iso8859-9e.c: Likewise.
+	* iconvdata/Makefile: Adjust appropriately.
+
+	[BZ #5428]
+	* wcsmbs/wchar.h: Unconditionally undefine __need_mbstate and
+	__need_wint_t.
+
 2007-12-07  Ulrich Drepper  <drepper@redhat.com>
 
 	[BZ #5427]
 	* iconvdata/hp-roman9.c: New file.
 	* iconvdata/Makefile: Add rules for hp-roman9.c.
 	* iconvdata/tst-tables.sh: Add HP-ROMAN9.
+	* iconvdata/gconv-modules: Likewise.
 
 	* iconvdata/hp-roman8.c: Use 8bit-gap instead of 8bit-generic.
 	* iconvdata/Makefile: Adjust appropriately.
diff --git a/NEWS b/NEWS
index 12bd32e199..c137977adf 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes.  2007-11-06
+GNU C Library NEWS -- history of user-visible changes.  2007-12-07
 Copyright (C) 1992-2006, 2007 Free Software Foundation, Inc.
 See the end for copying conditions.
 
@@ -8,6 +8,8 @@ using `glibc' in the "product" field.
 Version 2.8
 
 * New locales: bo_CN, bo_IN.
+
+* New encoding: HP-ROMAN9.
 
 Version 2.7
 
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index 7572f2789e..75ec7f06ea 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -217,13 +217,11 @@ install-others	= $(addprefix $(inst_gconvdir)/, $(modules.so))	\
 # We can build the conversion tables for numerous charsets automatically.
 
 gen-8bit-modules := iso8859-2 iso8859-3 iso8859-4 iso8859-6 iso8859-9 koi-8 \
-		    ebcdic-at-de ebcdic-at-de-a ebcdic-ca-fr		    \
-		    ebcdic-dk-no ebcdic-dk-no-a ebcdic-es ebcdic-es-a	    \
-		    ebcdic-es-s ebcdic-fi-se ebcdic-fi-se-a ebcdic-fr	    \
-		    ebcdic-is-friss ebcdic-it ebcdic-pt ebcdic-uk ebcdic-us \
+		    ebcdic-at-de ebcdic-at-de-a ebcdic-ca-fr ebcdic-dk-no   \
+		    ebcdic-dk-no-a ebcdic-es-s ebcdic-fi-se ebcdic-fi-se-a  \
+		    ebcdic-fr ebcdic-it ebcdic-pt ebcdic-us \
 		    ibm037 ibm038 ibm274 ibm275 ibm423 ibm500 ibm870 ibm871 \
-		    ibm891 ibm903 ibm904 ibm905 ibm1047 iso8859-16 viscii   \
-		    iso8859-9e
+		    ibm891 ibm903 ibm904 ibm905 ibm1047   \
 
 gen-8bit-gap-modules := koi8-r latin-greek latin-greek-1 ibm256 ibm273	   \
 			ibm277 ibm278 ibm280 ibm281 ibm284 ibm285 ibm290   \
@@ -240,8 +238,10 @@ gen-8bit-gap-modules := koi8-r latin-greek latin-greek-1 ibm256 ibm273	   \
 			iso8859-13 iso8859-14 iso8859-15 mac-uk sami-ws2   \
 			iso-ir-197 tis-620 koi8-u ibm874 cp10007 koi8-t	   \
 			georgian-ps georgian-academy iso-ir-209 mac-sami   \
-			iso8859-11 ibm866nav pt154 rk1048 mik brf \
-			mac-centraleurope koi8-ru hp-roman8 hp-roman9
+			iso8859-11 ibm866nav pt154 rk1048 mik brf	   \
+			mac-centraleurope koi8-ru hp-roman8 hp-roman9	   \
+			ebcdic-es ebcdic-es-a ebcdic-is-friss ebcdic-uk    \
+			iso8859-16 viscii iso8859-9e
 
 gen-special-modules := iso8859-7jp
 
diff --git a/iconvdata/ebcdic-es-a.c b/iconvdata/ebcdic-es-a.c
index ca8c980e6d..d056820cff 100644
--- a/iconvdata/ebcdic-es-a.c
+++ b/iconvdata/ebcdic-es-a.c
@@ -1,5 +1,5 @@
 /* Conversion from and to EBCDIC-ES-A.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -20,10 +20,10 @@
 
 #include <stdint.h>
 
-/* Get the conversion table.  */
-#include <ebcdic-es-a.h>
+/* Specify the conversion table.  */
+#define TABLES <ebcdic-es-a.h>
 
 #define CHARSET_NAME	"EBCDIC-ES-A//"
 #define HAS_HOLES	1	/* Not all 256 character are defined.  */
 
-#include <8bit-generic.c>
+#include <8bit-gap.c>
diff --git a/iconvdata/ebcdic-es.c b/iconvdata/ebcdic-es.c
index 4b471452bb..bb447c0376 100644
--- a/iconvdata/ebcdic-es.c
+++ b/iconvdata/ebcdic-es.c
@@ -1,5 +1,5 @@
 /* Conversion from and to EBCDIC-ES.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -20,10 +20,10 @@
 
 #include <stdint.h>
 
-/* Get the conversion table.  */
-#include <ebcdic-es.h>
+/* Specify the conversion table.  */
+#define TABLES <ebcdic-es.h>
 
 #define CHARSET_NAME	"EBCDIC-ES//"
 #define HAS_HOLES	1	/* Not all 256 character are defined.  */
 
-#include <8bit-generic.c>
+#include <8bit-gap.c>
diff --git a/iconvdata/ebcdic-is-friss.c b/iconvdata/ebcdic-is-friss.c
index cf9416f9ba..0a05ab2c9d 100644
--- a/iconvdata/ebcdic-is-friss.c
+++ b/iconvdata/ebcdic-is-friss.c
@@ -1,5 +1,5 @@
 /* Conversion from and to EBCDIC-IS-FRISS.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -20,10 +20,10 @@
 
 #include <stdint.h>
 
-/* Get the conversion table.  */
-#include <ebcdic-is-friss.h>
+/* Specify the conversion table.  */
+#define TABLES <ebcdic-is-friss.h>
 
 #define CHARSET_NAME	"EBCDIC-IS-FRISS//"
 #define HAS_HOLES	1	/* Not all 256 character are defined.  */
 
-#include <8bit-generic.c>
+#include <8bit-gap.c>
diff --git a/iconvdata/ebcdic-uk.c b/iconvdata/ebcdic-uk.c
index 7137a80981..ea9ff705ae 100644
--- a/iconvdata/ebcdic-uk.c
+++ b/iconvdata/ebcdic-uk.c
@@ -1,5 +1,5 @@
 /* Conversion from and to EBCDIC-UK.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -20,10 +20,10 @@
 
 #include <stdint.h>
 
-/* Get the conversion table.  */
-#include <ebcdic-uk.h>
+/* Specify the conversion table.  */
+#define TABLES <ebcdic-uk.h>
 
 #define CHARSET_NAME	"EBCDIC-UK//"
 #define HAS_HOLES	1	/* Not all 256 character are defined.  */
 
-#include <8bit-generic.c>
+#include <8bit-gap.c>
diff --git a/iconvdata/gconv-modules b/iconvdata/gconv-modules
index a8fcd8f0b3..dd3d372158 100644
--- a/iconvdata/gconv-modules
+++ b/iconvdata/gconv-modules
@@ -1927,3 +1927,10 @@ alias	ISO8859-9E//		ISO-8859-9E//
 alias	ISO88599E//		ISO-8859-9E//
 module	ISO-8859-9E//		INTERNAL		ISO8859-9E	1
 module	INTERNAL		ISO-8859-9E//		ISO8859-9E	1
+
+#	from			to			module		cost
+alias	ROMAN9//		HP-ROMAN9//
+alias	R9//			HP-ROMAN9//
+alias	HPROMAN9//		HP-ROMAN9//
+module	HP-ROMAN9//		INTERNAL		HP-ROMAN9	1
+module	INTERNAL		HP-ROMAN9//		HP-ROMAN9	1
diff --git a/iconvdata/iso8859-16.c b/iconvdata/iso8859-16.c
index 39857a628a..41ed591629 100644
--- a/iconvdata/iso8859-16.c
+++ b/iconvdata/iso8859-16.c
@@ -1,5 +1,5 @@
 /* Conversion from and to ISO 8859-16.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
 
@@ -18,11 +18,12 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* Get the conversion table.  */
 #include <stdint.h>
-#include <iso8859-16.h>
+
+/* Specify the conversion table.  */
+#define TABLES <iso8859-16.h>
 
 #define CHARSET_NAME "ISO-8859-16//"
 #define HAS_HOLES	0	/* All 256 character are defined.  */
 
-#include <8bit-generic.c>
+#include <8bit-gap.c>
diff --git a/iconvdata/iso8859-9e.c b/iconvdata/iso8859-9e.c
index 7048edac6f..300466399f 100644
--- a/iconvdata/iso8859-9e.c
+++ b/iconvdata/iso8859-9e.c
@@ -18,11 +18,12 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* Get the conversion table.  */
 #include <stdint.h>
-#include <iso8859-9e.h>
+
+/* Specify the conversion table.  */
+#define TABLES <iso8859-9e.h>
 
 #define CHARSET_NAME "ISO-8859-9E//"
 #define HAS_HOLES	0	/* All 256 character are defined.  */
 
-#include <8bit-generic.c>
+#include <8bit-gap.c>
diff --git a/iconvdata/viscii.c b/iconvdata/viscii.c
index 8e7d87e92b..672513d4d4 100644
--- a/iconvdata/viscii.c
+++ b/iconvdata/viscii.c
@@ -1,5 +1,5 @@
 /* Conversion from and to VISCII.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
 
@@ -18,11 +18,12 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* Get the conversion table.  */
 #include <stdint.h>
-#include <viscii.h>
+
+/* Specify the conversion table.  */
+#define TABLES <viscii.h>
 
 #define CHARSET_NAME	"VISCII//"
 #define HAS_HOLES	0	/* All 256 character are defined.  */
 
-#include <8bit-generic.c>
+#include <8bit-gap.c>
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index db622af22b..f9fc9da306 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -57,7 +57,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
 	 tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 bug15 \
 	 tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
 	 tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \
-	 bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21
+	 bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22
 
 test-srcs = tst-unbputc tst-printf
 
diff --git a/stdio-common/bug22.c b/stdio-common/bug22.c
new file mode 100644
index 0000000000..2228388b47
--- /dev/null
+++ b/stdio-common/bug22.c
@@ -0,0 +1,32 @@
+/* BZ #5424 */
+#include <stdio.h>
+
+#define N 2147483648
+
+#define STRINGIFY(S) #S
+#define MAKE_STR(S) STRINGIFY(S)
+
+#define SN MAKE_STR(N)
+
+static int
+do_test (void)
+{
+  int ret;
+
+  FILE *fp = fopen ("/dev/null", "w");
+  if (fp == NULL)
+    {
+      puts ("cannot open /dev/null");
+      return 1;
+    }
+
+  ret = fprintf (fp, "%" SN "d%" SN "d", 1, 1);
+
+  printf ("ret = %d\n", ret);
+
+  return ret != -1;
+}
+
+#define TIMEOUT 30
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index 434ad86b61..d10a5c6a13 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -64,6 +64,19 @@
     } while (0)
 #define UNBUFFERED_P(S) ((S)->_IO_file_flags & _IO_UNBUFFERED)
 
+#define done_add(val) \
+  do {									      \
+    unsigned int _val = val;						      \
+    assert ((unsigned int) done < (unsigned int) INT_MAX);		      \
+    if (__builtin_expect ((unsigned int) INT_MAX - (unsigned int) done	      \
+			  < _val, 0))					      \
+      {									      \
+	done = -1;							      \
+	goto all_done;							      \
+      }									      \
+    done += _val;							      \
+  } while (0)
+
 #ifndef COMPILE_WPRINTF
 # define vfprintf	_IO_vfprintf_internal
 # define CHAR_T		char
@@ -76,7 +89,7 @@
 # define PUT(F, S, N)	_IO_sputn ((F), (S), (N))
 # define PAD(Padchar) \
   if (width > 0)							      \
-    done += INTUSE(_IO_padn) (s, (Padchar), width)
+    done_add (INTUSE(_IO_padn) (s, (Padchar), width))
 # define PUTC(C, F)	_IO_putc_unlocked (C, F)
 # define ORIENT		if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, -1) != -1)\
 			  return -1
@@ -95,7 +108,7 @@
 # define PUT(F, S, N)	_IO_sputn ((F), (S), (N))
 # define PAD(Padchar) \
   if (width > 0)							      \
-    done += _IO_wpadn (s, (Padchar), width)
+    done_add (_IO_wpadn (s, (Padchar), width))
 # define PUTC(C, F)	_IO_putwc_unlocked (C, F)
 # define ORIENT		if (_IO_fwide (s, 1) != 1) return -1
 
@@ -116,20 +129,21 @@
   do									      \
     {									      \
       register const INT_T outc = (Ch);					      \
-      if (PUTC (outc, s) == EOF)					      \
+      if (PUTC (outc, s) == EOF || done == INT_MAX)			      \
 	{								      \
 	  done = -1;							      \
 	  goto all_done;						      \
 	}								      \
-      else								      \
-	++done;								      \
+      ++done;								      \
     }									      \
   while (0)
 
 #define outstring(String, Len)						      \
   do									      \
     {									      \
-      if ((size_t) PUT (s, (String), (Len)) != (size_t) (Len))		      \
+      assert ((size_t) done <= (size_t) INT_MAX);			      \
+      if ((size_t) PUT (s, (String), (Len)) != (size_t) (Len)		      \
+	  || (size_t) INT_MAX - (size_t) done < (size_t) (Len))		      \
 	{								      \
 	  done = -1;							      \
 	  goto all_done;						      \
@@ -811,7 +825,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    goto all_done;						      \
 	  }								      \
 									      \
-	done += function_done;						      \
+	done_add (function_done);					      \
       }									      \
       break;								      \
 									      \
@@ -865,7 +879,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 	    goto all_done;						      \
 	  }								      \
 									      \
-	done += function_done;						      \
+	done_add (function_done);					      \
       }									      \
       break;								      \
 									      \
@@ -1893,7 +1907,7 @@ do_positional:
 		  goto all_done;
 		}
 
-	      done += function_done;
+	      done_add (function_done);
 	    }
 	    break;
 	  }
diff --git a/time/Makefile b/time/Makefile
index 8ce34e4565..71d919d015 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -36,7 +36,7 @@ distribute := datemsk
 tests	:= test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
 	   tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
 	   tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
-	   tst-strptime3
+	   tst-strptime3 bug-getdate1
 
 include ../Rules
 
@@ -56,3 +56,5 @@ test_time-ARGS= EST5EDT CST
 
 tst-strptime-ENV = LOCPATH=${common-objpfx}localedata
 tst-ftime_l-ENV = LOCPATH=${common-objpfx}localedata
+
+bug-getdate1-ARGS = ${objpfx}bug-getdate1-fmt
diff --git a/time/bug-getdate1.c b/time/bug-getdate1.c
new file mode 100644
index 0000000000..7da88f4548
--- /dev/null
+++ b/time/bug-getdate1.c
@@ -0,0 +1,146 @@
+/* BZ #5451 */
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static char *templ_filename;
+
+// Writes template given as parameter to file,
+// specified as the argument
+static void
+output_to_template_file (const char *str)
+{
+  FILE *fd = fopen (templ_filename, "w");
+  if (fd == NULL)
+    {
+      printf ("Can not open file for writing\n");
+      exit (1);
+    }
+
+  fprintf (fd, "%s\n", str);
+  fclose (fd);
+}
+
+// Calls getdate() function with specified parameter,
+// specified as the argument, also checks the contents of
+// file with template and prints the result
+static int
+process_getdate_on (const char *str)
+{
+  struct tm *res;
+  char templ[1000];
+  FILE *fd = fopen (templ_filename, "r");
+
+  if (fd == NULL)
+    {
+      printf ("Can not open file for reading\n");
+      exit (1);
+    }
+
+  if (fgets (templ, 1000, fd) == NULL)
+    {
+      printf ("Can not read file\n");
+      exit (1);
+    }
+  fclose (fd);
+
+  res = getdate (str);
+  if (res == NULL)
+    {
+      printf ("Failed on getdate(\"%s\"), template is: %s", str, templ);
+      printf ("Error number: %d\n\n", getdate_err);
+      return 1;
+    }
+  printf ("Success on getdate(\"%s\"), template is: %s\n", str, templ);
+  printf ("Result is\n");
+  printf ("Seconds: %d\n", res->tm_sec);
+  printf ("Minutes: %d\n", res->tm_min);
+  printf ("Hour: %d\n", res->tm_hour);
+  printf ("Day of month: %d\n", res->tm_mday);
+  printf ("Month of year: %d\n", res->tm_mon);
+  printf ("Years since 1900: %d\n", res->tm_year);
+  printf ("Day of week: %d\n", res->tm_wday);
+  printf ("Day of year: %d\n", res->tm_yday);
+  printf ("Daylight Savings flag: %d\n\n", res->tm_isdst);
+  return 0;
+}
+
+static int
+do_test (int argc, char *argv[])
+{
+
+  templ_filename = argv[1];
+
+  setenv ("DATEMSK", templ_filename, 1);
+
+  /*
+   * The following 4 testcases reproduce the problem:
+   * 1. Templates "%S" and "%M" are not processed,
+   *    when used without "%H" template
+   */
+  int res = 0;
+  output_to_template_file ("%M");
+  res |= process_getdate_on ("1");
+
+  output_to_template_file ("%M %H");
+  res |= process_getdate_on ("1 2");
+
+  output_to_template_file ("%S");
+  res |= process_getdate_on ("1");
+
+  output_to_template_file ("%S %H");
+  res |= process_getdate_on ("1 2");
+
+  /*
+   * The following 9 testcases reproduce the problem:
+   * 2. Templates "%Y", "%y", "%d", "%C", "%C %y"
+   *    are not processed separately
+   */
+  output_to_template_file ("%Y");
+  process_getdate_on ("2001");
+
+  output_to_template_file ("%Y %m");
+  res |= process_getdate_on ("2001 3");
+
+  output_to_template_file ("%y");
+  res |= process_getdate_on ("70");
+
+  output_to_template_file ("%y %m");
+  res |= process_getdate_on ("70 3");
+
+  output_to_template_file ("%d");
+  res |= process_getdate_on ("06");
+
+  output_to_template_file ("%d %m");
+  res |= process_getdate_on ("25 3");
+
+  output_to_template_file ("%C");
+  res |= process_getdate_on ("98");
+
+  output_to_template_file ("%C %y %m");
+  res |= process_getdate_on ("98 3 2");
+
+  output_to_template_file ("%C %y");
+  res |= process_getdate_on ("21 5");
+
+  /*
+   * The following testcase reproduces the problem:
+   * 3. When template is "%Y %m", day of month is not set
+   *    to 1 as standard requires
+   */
+  output_to_template_file ("%Y %m");
+  res |= process_getdate_on ("2008 3");
+
+  return res;
+}
+
+#define PREPARE(argc, argv) \
+  if (argc < 2)								\
+    {									\
+      puts ("Command line: progname template_filename_full_path");	\
+      exit (1);								\
+    }									\
+  add_temp_file (argv[1])
+
+#define TEST_FUNCTION do_test (argc, argv)
+#include "../test-skeleton.c"
diff --git a/time/getdate.c b/time/getdate.c
index 851efacfd2..cbaa41dfd2 100644
--- a/time/getdate.c
+++ b/time/getdate.c
@@ -212,28 +212,31 @@ __getdate_r (const char *string, struct tm *tp)
       tp->tm_sec = tm.tm_sec;
     }
 
+  /* Fill in the gaps.  */
+  if (tp->tm_hour == INT_MIN)
+    tp->tm_hour = 0;
+  if (tp->tm_min == INT_MIN)
+    tp->tm_min = 0;
+  if (tp->tm_sec == INT_MIN)
+    tp->tm_sec = 0;
+
   /* If no date is given, today is assumed if the given hour is
      greater than the current hour and tomorrow is assumed if
      it is less.  */
   if (tp->tm_hour >= 0 && tp->tm_hour <= 23
-      && tp->tm_year == INT_MIN && tp->tm_mon == INT_MIN
+      && tp->tm_mon == INT_MIN
       && tp->tm_mday == INT_MIN && tp->tm_wday == INT_MIN)
     {
-      tp->tm_year = tm.tm_year;
       tp->tm_mon = tm.tm_mon;
       tp->tm_mday = tm.tm_mday + ((tp->tm_hour - tm.tm_hour) < 0 ? 1 : 0);
       mday_ok = 1;
     }
 
-  /* Fill in the gaps.  */
+  /* More fillers.  */
   if (tp->tm_year == INT_MIN)
     tp->tm_year = tm.tm_year;
-  if (tp->tm_hour == INT_MIN)
-    tp->tm_hour = 0;
-  if (tp->tm_min == INT_MIN)
-    tp->tm_min = 0;
-  if (tp->tm_sec == INT_MIN)
-    tp->tm_sec = 0;
+  if (tp->tm_mon == INT_MIN)
+    tp->tm_mon = tm.tm_mon;
 
   /* Check if the day of month is within range, and if the time can be
      represented in a time_t.  We make use of the fact that the mktime
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index 8702931115..0fd9e35440 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -839,4 +839,9 @@ __END_DECLS
 
 #endif	/* _WCHAR_H defined */
 
+/* Undefined all __need_* constants in case we are included to get those
+   constants but the whole file was already read.  */
+#undef __need_mbstate_t
+#undef __need_wint_t
+
 #endif /* wchar.h  */