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