On Mon, 7 Jan 2013, Jakub Jelinek wrote:
Won't the above preclude parsing 2147483640 up to 2147483647 ?
Because then in the last iteration count 214748364 > (INT_MAX - 9) / 10.

You're right -- thanks for catching that! Below is a patch with a more precise check.

Nickolai.

--- libiberty/cplus-dem.c       (revision 194959)
+++ libiberty/cplus-dem.c       (working copy)
@@ -48,7 +48,18 @@
 #include <sys/types.h>
 #include <string.h>
 #include <stdio.h>
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif

+#ifndef UINT_MAX
+#define UINT_MAX       ((unsigned int)(~0U))           /* 0xFFFFFFFF */
+#endif
+
+#ifndef INT_MAX
+#define INT_MAX                ((int)(UINT_MAX >> 1))            /* 0x7FFFFFFF 
*/
+#endif
+
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #else
@@ -494,28 +505,25 @@

   while (ISDIGIT ((unsigned char)**type))
     {
+      /* Check whether we can add another digit without overflow. */
+      if (count > INT_MAX / 10)
+       goto overflow;
+
       count *= 10;

-      /* Check for overflow.
-        We assume that count is represented using two's-complement;
-        no power of two is divisible by ten, so if an overflow occurs
-        when multiplying by ten, the result will not be a multiple of
-        ten.  */
-      if ((count % 10) != 0)
-       {
-         while (ISDIGIT ((unsigned char) **type))
-           (*type)++;
-         return -1;
-       }
+      if (count > INT_MAX - (**type - '0'))
+       goto overflow;

       count += **type - '0';
       (*type)++;
     }

-  if (count < 0)
-    count = -1;
+  return count;

-  return (count);
+ overflow:
+  while (ISDIGIT ((unsigned char) **type))
+    (*type)++;
+  return -1;
 }


Reply via email to