]> granicus.if.org Git - curl/commitdiff
parsedate: avoid integer overflow
authorEric Lubin <eric@lubin.us>
Wed, 11 Dec 2013 04:01:07 +0000 (20:01 -0800)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 11 Dec 2013 15:32:21 +0000 (16:32 +0100)
In C, signed integer overflow is undefined behavior. Thus, the compiler
is allowed to assume that it will not occur. In the check for an
overflow, the developer assumes that the signed integer of type time_t
will wrap around if it overflows. However, this behavior is undefined in
the C standard. Thus, when the compiler sees this, it simplifies t +
delta < t to delta < 0. Since delta > 0 and delta < 0 can't both be
true, the entire if statement is optimized out under certain
optimization levels. Thus, the parsedate function would return
PARSEDATE_OK with an undefined value in the time, instead of return -1 =
PARSEDATE_FAIL.

lib/parsedate.c

index 1ddd0080ae87459b2dcd0743174a4cda894ba16b..0262f13aaa26db2f551d2379c835029c428a785c 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -526,7 +526,7 @@ static int parsedate(const char *date, time_t *output)
     /* Add the time zone diff between local time zone and GMT. */
     long delta = (long)(tzoff!=-1?tzoff:0);
 
-    if((delta>0) && (t + delta < t))
+    if((delta>0) && (t > LONG_MAX  - delta))
       return -1; /* time_t overflow */
 
     t += delta;