diff options
| author | Paul Eggert | 2017-07-05 18:58:11 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-07-05 18:59:31 -0700 |
| commit | 018600f896fbed768e583f6b8ee7fbae713367d1 (patch) | |
| tree | d1e450e753f1d76c4c848330e80c69b6c39f80ea /src/image.c | |
| parent | d6662694d05be03fdd070353637dd22a324c8b7a (diff) | |
| download | emacs-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.c | 23 |
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 = | |||
| 2444 | enum xbm_token | 2444 | enum 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 | { |