emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 018600f 3/3: Check for integer overflow in xbm imag


From: Paul Eggert
Subject: [Emacs-diffs] master 018600f 3/3: Check for integer overflow in xbm images
Date: Wed, 5 Jul 2017 21:59:37 -0400 (EDT)

branch: master
commit 018600f896fbed768e583f6b8ee7fbae713367d1
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Check for integer overflow in xbm images
    
    * src/image.c (XBM_TK_OVERFLOW): New constant.
    (xbm_scan): Check for integer overflow instead of relying on
    undefined behavior.  Check that octal digits are actually octal.
---
 src/image.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/image.c b/src/image.c
index 6b748ba..91749fb 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2444,7 +2444,8 @@ static struct image_type xbm_type =
 enum xbm_token
 {
   XBM_TK_IDENT = 256,
-  XBM_TK_NUMBER
+  XBM_TK_NUMBER,
+  XBM_TK_OVERFLOW
 };
 
 
@@ -2586,6 +2587,7 @@ xbm_scan (char **s, char *end, char *sval, int *ival)
   else if (c_isdigit (c))
     {
       int value = 0, digit;
+      bool overflow = false;
 
       if (c == '0' && *s < end)
        {
@@ -2598,15 +2600,19 @@ xbm_scan (char **s, char *end, char *sval, int *ival)
                  digit = char_hexdigit (c);
                  if (digit < 0)
                    break;
-                 value = 16 * value + digit;
+                 overflow |= INT_MULTIPLY_WRAPV (value, 16, &value);
+                 value += digit;
                }
            }
-         else if (c_isdigit (c))
+         else if ('0' <= c && c <= '7')
            {
              value = c - '0';
              while (*s < end
-                    && (c = *(*s)++, c_isdigit (c)))
-               value = 8 * value + c - '0';
+                    && (c = *(*s)++, '0' <= c && c <= '7'))
+               {
+                 overflow |= INT_MULTIPLY_WRAPV (value, 8, &value);
+                 value += c - '0';
+               }
            }
        }
       else
@@ -2614,13 +2620,16 @@ xbm_scan (char **s, char *end, char *sval, int *ival)
          value = c - '0';
          while (*s < end
                 && (c = *(*s)++, c_isdigit (c)))
-           value = 10 * value + c - '0';
+           {
+             overflow |= INT_MULTIPLY_WRAPV (value, 10, &value);
+             overflow |= INT_ADD_WRAPV (value, c - '0', &value);
+           }
        }
 
       if (*s < end)
        *s = *s - 1;
       *ival = value;
-      return XBM_TK_NUMBER;
+      return overflow ? XBM_TK_OVERFLOW : XBM_TK_NUMBER;
     }
   else if (c_isalpha (c) || c == '_')
     {



reply via email to

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