]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix assertion failure when reading 'BIGNUM.'
authorPaul Eggert <eggert@Penguin.CS.UCLA.EDU>
Tue, 21 Aug 2018 22:49:01 +0000 (15:49 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 21 Aug 2018 22:51:05 +0000 (15:51 -0700)
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
test/src/lread-tests.el

index df2fe5812039e056cdf0cdbcb96e648bfbbb90e5..5e1bd419fa4da37cd4ae7b0cd4c99065253be162 100644 (file)
@@ -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.
index 17381340c7bfa13b64ce3416d3a3a1f5580ee9a4..f19d98320abed646b7a3c5c92c4d8dc8b28f51ff 100644 (file)
@@ -209,4 +209,13 @@ literals (Bug#20852)."
   (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