bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: avoid integer overflow in mktime.m4


From: Paul Eggert
Subject: Re: avoid integer overflow in mktime.m4
Date: Fri, 22 Dec 2006 00:50:15 -0800
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

I installed the following into Autoconf to fix the Autoconf side of
the problem.

2006-12-22  Paul Eggert  <address@hidden>

        * lib/autoconf/functions.m4 (AC_FUNC_MKTIME):
        Include <limits.h>, and use its INT_MAX to rewrite the
        j loop so that it does not overflow 'int'.  Problem reported by
        Ralf Wildenhues in
        <http://lists.gnu.org/archive/html/bug-gnulib/2006-12/msg00084.html>.
        Play it safe by shifting left by 1 rather than multiplying by 2,
        as GCC is less likely to optimize this away when the value
        is signed (when it assumes overflow leads to undefined behavior).
        Also, don't assume time_t uses two's complement.

Index: lib/autoconf/functions.m4
===================================================================
RCS file: /cvsroot/autoconf/autoconf/lib/autoconf/functions.m4,v
retrieving revision 1.118
diff -u -p -r1.118 functions.m4
--- lib/autoconf/functions.m4   16 Dec 2006 05:38:41 -0000      1.118
+++ lib/autoconf/functions.m4   22 Dec 2006 08:41:23 -0000
@@ -984,6 +984,7 @@ AC_CACHE_CHECK([for working mktime], ac_
 # endif
 #endif

+#include <limits.h>
 #include <stdlib.h>

 #ifdef HAVE_UNISTD_H
@@ -1132,12 +1133,15 @@ main ()
      isn't worth using anyway.  */
   alarm (60);

-  for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2)
-    continue;
-  time_t_max--;
-  if ((time_t) -1 < 0)
-    for (time_t_min = -1; (time_t) (time_t_min * 2) < 0; time_t_min *= 2)
-      continue;
+  for (;;)
+    {
+      t = (time_t_max << 1) + 1;
+      if (t <= time_t_max)
+       break;
+      time_t_max = t;
+    }
+  time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max;
+
   delta = time_t_max / 997; /* a suitable prime number */
   for (i = 0; i < N_STRINGS; i++)
     {
@@ -1152,10 +1156,12 @@ main ()
             && mktime_test ((time_t) (60 * 60 * 24))))
        return 1;

-      for (j = 1; 0 < j; j *= 2)
+      for (j = 1; ; j <<= 1)
        if (! bigtime_test (j))
          return 1;
-      if (! bigtime_test (j - 1))
+       else if (INT_MAX / 2 < j)
+         break;
+      if (! bigtime_test (INT_MAX))
        return 1;
     }
   return ! (irix_6_4_bug () && spring_forward_gap () && year_2050_test ());




reply via email to

[Prev in Thread] Current Thread [Next in Thread]