about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2013-04-10 11:31:46 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2013-04-10 11:31:46 +0530
commitabe7f530bf5c741fe6f0658da7be59d8db168f7f (patch)
treeb57ba83c808a98b42b5b9d548afc51ae6962982d
parent61c23e6234db0e94cd850e88536401910ac61516 (diff)
downloadglibc-abe7f530bf5c741fe6f0658da7be59d8db168f7f.tar.gz
glibc-abe7f530bf5c741fe6f0658da7be59d8db168f7f.tar.xz
glibc-abe7f530bf5c741fe6f0658da7be59d8db168f7f.zip
Accept leading and trailing spaces in getdate input string
Fixes #15346.

The POSIX description of getdate allows for extra spaces in the
getdate input string.  __getdate_r uses strptime internally, which
works fine with extra spaces between format strings (and hence within
an input string) but not with leading and trailing spaces.  So we trim
off the leading and trailing spaces before we pass it on to strptime.
-rw-r--r--ChangeLog10
-rw-r--r--NEWS2
-rw-r--r--time/getdate.c42
-rw-r--r--time/tst-getdate.c4
4 files changed, 57 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 20be985630..411522580f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2013-04-10  Siddhesh Poyarekar  <siddhesh@redhat.com>
+	    Roland McGrath  <roland@hack.frob.com>
+	    Ondrej Bilka  <neleai@seznam.cz>
+
+	[BZ #15346]
+	* time/getdate.c: Include ctype.h and alloca.h.
+	(__getdate_r): Trim leading and trailing spaces of input.
+	* time/tst-getdate.c (tests): Add tests with leading and
+	trailing spaces.
+
 2013-04-08  Roland McGrath  <roland@hack.frob.com>
 
 	[BZ #14280]
diff --git a/NEWS b/NEWS
index 5644a59a75..17a997aefa 100644
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,7 @@ Version 2.18
   14981, 14982, 14985, 14994, 14996, 15003, 15006, 15020, 15023, 15036,
   15054, 15055, 15062, 15078, 15160, 15214, 15232, 15234, 15283, 15285,
   15287, 15304, 15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337,
-  15342.
+  15342, 15346.
 
 * CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
   #15078).
diff --git a/time/getdate.c b/time/getdate.c
index 637dd18fcf..eadebc348b 100644
--- a/time/getdate.c
+++ b/time/getdate.c
@@ -25,6 +25,8 @@
 #include <time.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <ctype.h>
+#include <alloca.h>
 
 #define TM_YEAR_BASE 1900
 
@@ -135,6 +137,44 @@ __getdate_r (const char *string, struct tm *tp)
   /* No threads reading this stream.  */
   __fsetlocking (fp, FSETLOCKING_BYCALLER);
 
+  /* Skip leading whitespace.  */
+  while (isspace (*string))
+    string++;
+
+  size_t inlen, oldlen;
+
+  oldlen = inlen = strlen (string);
+
+  /* Skip trailing whitespace.  */
+  while (inlen > 0 && isspace (string[inlen - 1]))
+    inlen--;
+
+  char *instr = NULL;
+
+  if (inlen < oldlen)
+    {
+      bool using_malloc = false;
+
+      if (__libc_use_alloca (inlen + 1))
+	instr = alloca (inlen + 1);
+      else
+	{
+	  instr = malloc (inlen + 1);
+	  if (instr == NULL)
+	    {
+	      fclose (fp);
+	      return 6;
+	    }
+	  using_malloc = true;
+	}
+      memcpy (instr, string, inlen);
+      instr[inlen] = '\0';
+      string = instr;
+
+      if (!using_malloc)
+	instr = NULL;
+    }
+
   line = NULL;
   len = 0;
   do
@@ -159,6 +199,8 @@ __getdate_r (const char *string, struct tm *tp)
     }
   while (!feof_unlocked (fp));
 
+  free (instr);
+
   /* Free the buffer.  */
   free (line);
 
diff --git a/time/tst-getdate.c b/time/tst-getdate.c
index 7604e8394f..dc8ecf413a 100644
--- a/time/tst-getdate.c
+++ b/time/tst-getdate.c
@@ -31,6 +31,10 @@ static const struct
 } tests [] =
 {
   {"21:01:10 1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
+  {"21:01:10    1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
+  {"   21:01:10 1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
+  {"21:01:10 1999-1-31   ", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
+  {"    21:01:10 1999-1-31   ", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}},
   {"21:01:10 1999-2-28", "Universal", 0, {10, 1, 21, 28, 1, 99, 0, 0, 0}},
   {"16:30:46 2000-2-29", "Universal", 0, {46, 30,16, 29, 1, 100, 0, 0, 0}},
   {"01-08-2000 05:06:07", "Europe/Berlin", 0, {7, 6, 5, 1, 7, 100, 0, 0, 0}}