diff options
| author | Paul Eggert | 2018-04-17 16:23:16 -0700 |
|---|---|---|
| committer | Paul Eggert | 2018-04-17 16:23:48 -0700 |
| commit | 5dff4905d73d0d42447ff4b114d1af726a689c6a (patch) | |
| tree | c16f884351acf0c7fcdc023604f22dd11e7b88f3 /src | |
| parent | 2457d10ebfedbd24040e30e70cca90c6e523afe0 (diff) | |
| download | emacs-5dff4905d73d0d42447ff4b114d1af726a689c6a.tar.gz emacs-5dff4905d73d0d42447ff4b114d1af726a689c6a.zip | |
Fix signal for large integers with valid syntax
* src/lread.c (read_integer): If a radixed integer has valid syntax
but is waayyy too large, signal overflow instead of invalid syntax.
* test/src/lread-tests.el (lread-long-hex-integer): New test.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lread.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/src/lread.c b/src/lread.c index 65d22af6937..6eda7405409 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -2644,14 +2644,13 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix) | |||
| 2644 | Also, room for invalid syntax diagnostic. */ | 2644 | Also, room for invalid syntax diagnostic. */ |
| 2645 | char buf[max (1 + 1 + UINTMAX_WIDTH + 1, | 2645 | char buf[max (1 + 1 + UINTMAX_WIDTH + 1, |
| 2646 | sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT))]; | 2646 | sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT))]; |
| 2647 | 2647 | char *p = buf; | |
| 2648 | int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */ | 2648 | int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */ |
| 2649 | 2649 | ||
| 2650 | if (radix < 2 || radix > 36) | 2650 | if (radix < 2 || radix > 36) |
| 2651 | valid = 0; | 2651 | valid = 0; |
| 2652 | else | 2652 | else |
| 2653 | { | 2653 | { |
| 2654 | char *p = buf; | ||
| 2655 | int c, digit; | 2654 | int c, digit; |
| 2656 | 2655 | ||
| 2657 | c = READCHAR; | 2656 | c = READCHAR; |
| @@ -2679,17 +2678,12 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix) | |||
| 2679 | valid = 0; | 2678 | valid = 0; |
| 2680 | if (valid < 0) | 2679 | if (valid < 0) |
| 2681 | valid = 1; | 2680 | valid = 1; |
| 2682 | 2681 | *p = c; | |
| 2683 | if (p < buf + sizeof buf - 1) | 2682 | p += p < buf + sizeof buf; |
| 2684 | *p++ = c; | ||
| 2685 | else | ||
| 2686 | valid = 0; | ||
| 2687 | |||
| 2688 | c = READCHAR; | 2683 | c = READCHAR; |
| 2689 | } | 2684 | } |
| 2690 | 2685 | ||
| 2691 | UNREAD (c); | 2686 | UNREAD (c); |
| 2692 | *p = '\0'; | ||
| 2693 | } | 2687 | } |
| 2694 | 2688 | ||
| 2695 | if (valid != 1) | 2689 | if (valid != 1) |
| @@ -2698,6 +2692,13 @@ read_integer (Lisp_Object readcharfun, EMACS_INT radix) | |||
| 2698 | invalid_syntax (buf); | 2692 | invalid_syntax (buf); |
| 2699 | } | 2693 | } |
| 2700 | 2694 | ||
| 2695 | if (p == buf + sizeof buf) | ||
| 2696 | { | ||
| 2697 | memset (p - 3, '.', 3); | ||
| 2698 | xsignal1 (Qoverflow_error, make_unibyte_string (buf, sizeof buf)); | ||
| 2699 | } | ||
| 2700 | |||
| 2701 | *p = '\0'; | ||
| 2701 | return string_to_number (buf, radix, 0); | 2702 | return string_to_number (buf, radix, 0); |
| 2702 | } | 2703 | } |
| 2703 | 2704 | ||