From abe7f530bf5c741fe6f0658da7be59d8db168f7f Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Wed, 10 Apr 2013 11:31:46 +0530 Subject: [PATCH] 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. --- ChangeLog | 10 ++++++++++ NEWS | 2 +- time/getdate.c | 42 ++++++++++++++++++++++++++++++++++++++++++ time/tst-getdate.c | 4 ++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 20be985..4115225 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2013-04-10 Siddhesh Poyarekar + Roland McGrath + Ondrej Bilka + + [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 [BZ #14280] diff --git a/NEWS b/NEWS index 5644a59..17a997a 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 637dd18..eadebc3 100644 --- a/time/getdate.c +++ b/time/getdate.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #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 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}} -- 2.7.4