From: Jim Meyering Date: Wed, 4 Jul 2012 10:58:07 +0000 (+0200) Subject: parse-datetime: fix failure to diagnose invalid input X-Git-Tag: v0.1~564 X-Git-Url: http://erislabs.net/gitweb/?p=gnulib.git;a=commitdiff_plain;h=d8f90adf5f01512958b6da46bd5eea01294a434e parse-datetime: fix failure to diagnose invalid input date -d "$(printf '\xb0')" would print 00:00:00 with today's date rather than diagnosing the invalid input. Now it reports this: date: invalid date '\260' * lib/parse-datetime.y (to_uchar): Define. (yylex): Don't sign-extend "other" bytes. * m4/parse-datetime.m4: Require AC_C_INLINE for first use of "inline". Thanks to Bruno Haible for the patch to this file. * tests/test-parse-datetime.c (main): Add a test to trigger the bug. Peter Evans reported the bug in GNU date: http://bugs.gnu.org/11843 --- diff --git a/ChangeLog b/ChangeLog index 5edb6d46a..cd3ba33b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2012-07-04 Jim Meyering + + parse-datetime: fix failure to diagnose invalid input + date -d "$(printf '\xb0')" would print 00:00:00 with today's date + rather than diagnosing the invalid input. Now it reports this: + date: invalid date '\260' + * lib/parse-datetime.y (to_uchar): Define. + (yylex): Don't sign-extend "other" bytes. + * m4/parse-datetime.m4: Require AC_C_INLINE for first use of "inline". + Thanks to Bruno Haible for the patch to this file. + * tests/test-parse-datetime.c (main): Add a test to trigger the bug. + Peter Evans reported the bug in GNU date: http://bugs.gnu.org/11843 + 2012-07-03 Jim Meyering bootstrap: do not require now-removed build-aux/missing diff --git a/lib/parse-datetime.y b/lib/parse-datetime.y index 67669f631..4d9f65ab2 100644 --- a/lib/parse-datetime.y +++ b/lib/parse-datetime.y @@ -113,6 +113,11 @@ typedef long int long_time_t; typedef time_t long_time_t; #endif +/* Convert a possibly-signed character to an unsigned character. This is + a bit safer than casting to unsigned char, since it catches some type + errors that the cast doesn't. */ +static inline unsigned char to_uchar (char ch) { return ch; } + /* Lots of this code assumes time_t and time_t-like values fit into long_time_t. */ verify (TYPE_MINIMUM (long_time_t) <= TYPE_MINIMUM (time_t) @@ -1171,7 +1176,8 @@ yylex (YYSTYPE *lvalp, parser_control *pc) } if (c != '(') - return *pc->input++; + return to_uchar (*pc->input++); + count = 0; do { diff --git a/m4/parse-datetime.m4 b/m4/parse-datetime.m4 index 8efefbe8c..3fb2d2b55 100644 --- a/m4/parse-datetime.m4 +++ b/m4/parse-datetime.m4 @@ -1,4 +1,4 @@ -# parse-datetime.m4 serial 19 +# parse-datetime.m4 serial 20 dnl Copyright (C) 2002-2006, 2008-2012 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -32,6 +32,7 @@ AC_DEFUN([gl_PARSE_DATETIME], dnl Prerequisites of lib/parse-datetime.y. AC_REQUIRE([gl_BISON]) + AC_REQUIRE([AC_C_INLINE]) AC_REQUIRE([gl_C_COMPOUND_LITERALS]) AC_STRUCT_TIMEZONE AC_REQUIRE([gl_CLOCK_TIME]) diff --git a/tests/test-parse-datetime.c b/tests/test-parse-datetime.c index 4c0370d29..1c9fd2dbd 100644 --- a/tests/test-parse-datetime.c +++ b/tests/test-parse-datetime.c @@ -409,5 +409,9 @@ main (int argc _GL_UNUSED, char **argv) ASSERT (result.tv_sec == 24 * 3600 && result.tv_nsec == now.tv_nsec); + /* Exercise a sign-extension bug. Before July 2012, an input + starting with a high-bit-set byte would be treated like "0". */ + ASSERT ( ! parse_datetime (&result, "\xb0", &now)); + return 0; }