>From f8069952abf147d090032ad6b941a728cad2c496 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 21 Aug 2018 15:49:01 -0700 Subject: [PATCH] Fix assertion failure when reading 'BIGNUM.' Problem reported by Stefan Monnier (Bug#32476). * src/lread.c (string_to_number): Don't pass leading "+" or trailing "." or junk to make_bignum_str. * test/src/lread-tests.el (lread-string-to-number-trailing-dot): New test. --- src/lread.c | 21 ++++++++++++++++----- test/src/lread-tests.el | 9 +++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/lread.c b/src/lread.c index df2fe58120..5e1bd419fa 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3710,8 +3710,9 @@ string_to_number (char const *string, int base, int flags) IEEE floating point hosts, and works around a formerly-common bug where atof ("-0.0") drops the sign. */ bool negative = *cp == '-'; + bool positive = *cp == '+'; - bool signedp = negative || *cp == '+'; + bool signedp = negative | positive; cp += signedp; enum { INTOVERFLOW = 1, LEAD_INT = 2, DOT_CHAR = 4, TRAIL_INT = 8, @@ -3732,6 +3733,7 @@ string_to_number (char const *string, int base, int flags) n += digit; } } + char const *after_digits = cp; if (*cp == '.') { state |= DOT_CHAR; @@ -3807,10 +3809,19 @@ string_to_number (char const *string, int base, int flags) return make_fixnum (negative ? -signed_n : signed_n); } - /* Skip a leading "+". */ - if (signedp && !negative) - ++string; - return make_bignum_str (string, base); + /* Trim any leading "+" and trailing nondigits, then convert to + bignum. */ + string += positive; + if (!*after_digits) + return make_bignum_str (string, base); + ptrdiff_t trimmed_len = after_digits - string; + USE_SAFE_ALLOCA; + char *trimmed = SAFE_ALLOCA (trimmed_len + 1); + memcpy (trimmed, string, trimmed_len); + trimmed[trimmed_len] = '\0'; + Lisp_Object result = make_bignum_str (trimmed, base); + SAFE_FREE (); + return result; } /* Either the number uses float syntax, or it does not fit into a fixnum. diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el index 17381340c7..f19d98320a 100644 --- a/test/src/lread-tests.el +++ b/test/src/lread-tests.el @@ -209,4 +209,13 @@ lread-tests--last-message (should-error (let ((load-force-doc-strings t)) (read "#[0 \"\"]")))) +(ert-deftest lread-string-to-number-trailing-dot () + (dolist (n (list (* most-negative-fixnum most-negative-fixnum) + (1- most-negative-fixnum) most-negative-fixnum + (1+ most-negative-fixnum) -1 0 1 + (1- most-positive-fixnum) most-positive-fixnum + (1+ most-positive-fixnum) + (* most-positive-fixnum most-positive-fixnum))) + (should (= n (string-to-number (format "%d." n)))))) + ;;; lread-tests.el ends here -- 2.17.1