ce426f
commit abe7f530bf5c741fe6f0658da7be59d8db168f7f
ce426f
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
ce426f
Date:   Wed Apr 10 11:31:46 2013 +0530
ce426f
ce426f
    Accept leading and trailing spaces in getdate input string
ce426f
    
ce426f
    Fixes #15346.
ce426f
    
ce426f
    The POSIX description of getdate allows for extra spaces in the
ce426f
    getdate input string.  __getdate_r uses strptime internally, which
ce426f
    works fine with extra spaces between format strings (and hence within
ce426f
    an input string) but not with leading and trailing spaces.  So we trim
ce426f
    off the leading and trailing spaces before we pass it on to strptime.
ce426f
ce426f
diff --git glibc-2.17-c758a686/time/getdate.c glibc-2.17-c758a686/time/getdate.c
ce426f
index 637dd18..eadebc3 100644
ce426f
--- glibc-2.17-c758a686/time/getdate.c
ce426f
+++ glibc-2.17-c758a686/time/getdate.c
ce426f
@@ -25,6 +25,8 @@
ce426f
 #include <time.h>
ce426f
 #include <unistd.h>
ce426f
 #include <sys/stat.h>
ce426f
+#include <ctype.h>
ce426f
+#include <alloca.h>
ce426f
 
ce426f
 #define TM_YEAR_BASE 1900
ce426f
 
ce426f
@@ -135,6 +137,44 @@ __getdate_r (const char *string, struct tm *tp)
ce426f
   /* No threads reading this stream.  */
ce426f
   __fsetlocking (fp, FSETLOCKING_BYCALLER);
ce426f
 
ce426f
+  /* Skip leading whitespace.  */
ce426f
+  while (isspace (*string))
ce426f
+    string++;
ce426f
+
ce426f
+  size_t inlen, oldlen;
ce426f
+
ce426f
+  oldlen = inlen = strlen (string);
ce426f
+
ce426f
+  /* Skip trailing whitespace.  */
ce426f
+  while (inlen > 0 && isspace (string[inlen - 1]))
ce426f
+    inlen--;
ce426f
+
ce426f
+  char *instr = NULL;
ce426f
+
ce426f
+  if (inlen < oldlen)
ce426f
+    {
ce426f
+      bool using_malloc = false;
ce426f
+
ce426f
+      if (__libc_use_alloca (inlen + 1))
ce426f
+	instr = alloca (inlen + 1);
ce426f
+      else
ce426f
+	{
ce426f
+	  instr = malloc (inlen + 1);
ce426f
+	  if (instr == NULL)
ce426f
+	    {
ce426f
+	      fclose (fp);
ce426f
+	      return 6;
ce426f
+	    }
ce426f
+	  using_malloc = true;
ce426f
+	}
ce426f
+      memcpy (instr, string, inlen);
ce426f
+      instr[inlen] = '\0';
ce426f
+      string = instr;
ce426f
+
ce426f
+      if (!using_malloc)
ce426f
+	instr = NULL;
ce426f
+    }
ce426f
+
ce426f
   line = NULL;
ce426f
   len = 0;
ce426f
   do
ce426f
@@ -159,6 +199,8 @@ __getdate_r (const char *string, struct tm *tp)
ce426f
     }
ce426f
   while (!feof_unlocked (fp));
ce426f
 
ce426f
+  free (instr);
ce426f
+
ce426f
   /* Free the buffer.  */
ce426f
   free (line);
ce426f
 
ce426f
diff --git glibc-2.17-c758a686/time/tst-getdate.c glibc-2.17-c758a686/time/tst-getdate.c
ce426f
index 7604e83..dc8ecf4 100644
ce426f
--- glibc-2.17-c758a686/time/tst-getdate.c
ce426f
+++ glibc-2.17-c758a686/time/tst-getdate.c
ce426f
@@ -31,6 +31,10 @@ static const struct
ce426f
 } tests [] =
ce426f
 {
ce426f
   {"21:01:10 1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
ce426f
+  {"21:01:10    1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
ce426f
+  {"   21:01:10 1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
ce426f
+  {"21:01:10 1999-1-31   ", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
ce426f
+  {"    21:01:10 1999-1-31   ", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
ce426f
   {"21:01:10 1999-2-28", "Universal", 0, {10, 1, 21, 28, 1, 99, 0, 0, 0}},
ce426f
   {"16:30:46 2000-2-29", "Universal", 0, {46, 30,16, 29, 1, 100, 0, 0, 0}},
ce426f
   {"01-08-2000 05:06:07", "Europe/Berlin", 0, {7, 6, 5, 1, 7, 100, 0, 0, 0}}