This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v3][BZ #15346] Allow leading and trailing spaces in getdate


Thanks, here's an updated patch with the feedback incorporated.

Siddhesh


commit 80fa6fa933651974d0f5e4050b458fe17efc1577
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Tue Apr 9 10:01:32 2013 +0530

    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.
    
    ---
    
	[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.

diff --git a/time/getdate.c b/time/getdate.c
index 637dd18..472debf 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,37 @@ __getdate_r (const char *string, struct tm *tp)
   /* No threads reading this stream.  */
   __fsetlocking (fp, FSETLOCKING_BYCALLER);
 
+  size_t inlen = strlen (string);
+  int i = 0;
+  bool free_instr = false;
+
+  /* Skip leading whitespace.  */
+  while (isspace (string[i]))
+    i++;
+
+  /* Skip trailing whitespace.  */
+  while (inlen > i && isspace (string[inlen - 1]))
+    inlen--;
+
+  inlen -= i;
+
+  char *instr;
+  if (__libc_use_alloca (inlen + 1))
+    instr = alloca (inlen + 1);
+  else
+    {
+      instr = malloc (inlen + 1);
+      if (instr == NULL)
+	{
+	  fclose (fp);
+	  return 6;
+	}
+      free_instr = true;
+    }
+
+  memcpy (instr, string + i, inlen);
+  instr[inlen] = '\0';
+
   line = NULL;
   len = 0;
   do
@@ -153,12 +186,15 @@ __getdate_r (const char *string, struct tm *tp)
       tp->tm_isdst = -1;
       tp->tm_gmtoff = 0;
       tp->tm_zone = NULL;
-      result = strptime (string, line, tp);
+      result = strptime (instr, line, tp);
       if (result && *result == '\0')
 	break;
     }
   while (!feof_unlocked (fp));
 
+  if (free_instr)
+    free (instr);
+
   /* Free the buffer.  */
   free (line);
 
diff --git a/time/tst-getdate.c b/time/tst-getdate.c
index 7604e83..dc8ecf4 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}}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]