aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorPaul Eggert2017-07-05 18:58:11 -0700
committerPaul Eggert2017-07-05 18:59:31 -0700
commit018600f896fbed768e583f6b8ee7fbae713367d1 (patch)
treed1e450e753f1d76c4c848330e80c69b6c39f80ea /src/image.c
parentd6662694d05be03fdd070353637dd22a324c8b7a (diff)
downloademacs-018600f896fbed768e583f6b8ee7fbae713367d1.tar.gz
emacs-018600f896fbed768e583f6b8ee7fbae713367d1.zip
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.
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/src/image.c b/src/image.c
index 6b748ba2af6..91749fb8733 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2444,7 +2444,8 @@ static struct image_type xbm_type =
2444enum xbm_token 2444enum xbm_token
2445{ 2445{
2446 XBM_TK_IDENT = 256, 2446 XBM_TK_IDENT = 256,
2447 XBM_TK_NUMBER 2447 XBM_TK_NUMBER,
2448 XBM_TK_OVERFLOW
2448}; 2449};
2449 2450
2450 2451
@@ -2586,6 +2587,7 @@ xbm_scan (char **s, char *end, char *sval, int *ival)
2586 else if (c_isdigit (c)) 2587 else if (c_isdigit (c))
2587 { 2588 {
2588 int value = 0, digit; 2589 int value = 0, digit;
2590 bool overflow = false;
2589 2591
2590 if (c == '0' && *s < end) 2592 if (c == '0' && *s < end)
2591 { 2593 {
@@ -2598,15 +2600,19 @@ xbm_scan (char **s, char *end, char *sval, int *ival)
2598 digit = char_hexdigit (c); 2600 digit = char_hexdigit (c);
2599 if (digit < 0) 2601 if (digit < 0)
2600 break; 2602 break;
2601 value = 16 * value + digit; 2603 overflow |= INT_MULTIPLY_WRAPV (value, 16, &value);
2604 value += digit;
2602 } 2605 }
2603 } 2606 }
2604 else if (c_isdigit (c)) 2607 else if ('0' <= c && c <= '7')
2605 { 2608 {
2606 value = c - '0'; 2609 value = c - '0';
2607 while (*s < end 2610 while (*s < end
2608 && (c = *(*s)++, c_isdigit (c))) 2611 && (c = *(*s)++, '0' <= c && c <= '7'))
2609 value = 8 * value + c - '0'; 2612 {
2613 overflow |= INT_MULTIPLY_WRAPV (value, 8, &value);
2614 value += c - '0';
2615 }
2610 } 2616 }
2611 } 2617 }
2612 else 2618 else
@@ -2614,13 +2620,16 @@ xbm_scan (char **s, char *end, char *sval, int *ival)
2614 value = c - '0'; 2620 value = c - '0';
2615 while (*s < end 2621 while (*s < end
2616 && (c = *(*s)++, c_isdigit (c))) 2622 && (c = *(*s)++, c_isdigit (c)))
2617 value = 10 * value + c - '0'; 2623 {
2624 overflow |= INT_MULTIPLY_WRAPV (value, 10, &value);
2625 overflow |= INT_ADD_WRAPV (value, c - '0', &value);
2626 }
2618 } 2627 }
2619 2628
2620 if (*s < end) 2629 if (*s < end)
2621 *s = *s - 1; 2630 *s = *s - 1;
2622 *ival = value; 2631 *ival = value;
2623 return XBM_TK_NUMBER; 2632 return overflow ? XBM_TK_OVERFLOW : XBM_TK_NUMBER;
2624 } 2633 }
2625 else if (c_isalpha (c) || c == '_') 2634 else if (c_isalpha (c) || c == '_')
2626 { 2635 {