~ chicken-core (chicken-5) 96286a7a7144b17e4b7a3f08164fb6d6296f1722


commit 96286a7a7144b17e4b7a3f08164fb6d6296f1722
Author:     Peter Bex <peter.bex@xs4all.nl>
AuthorDate: Sun Sep 18 18:15:13 2011 +0200
Commit:     Peter Bex <peter.bex@xs4all.nl>
CommitDate: Sun Sep 18 18:15:13 2011 +0200

    Fix decode_literal not to use system functions strtol() and strtod() but convert_string_to_number(), which is the inverse of the function(s) used in encode-literal.  This fixes a panic bug when reading back infs or nans, which is triggered by the change in 139f7e9cdba897bc0969e761aede66218fcabb11 but which could also have cropped up before, when cross-compiling

diff --git a/runtime.c b/runtime.c
index 5f8a0caa..13e16e23 100644
--- a/runtime.c
+++ b/runtime.c
@@ -8782,7 +8782,6 @@ static C_regparm C_word C_fcall decode_literal2(C_word **ptr, C_char **str,
   unsigned long bits = *((*str)++) & 0xff;
   C_word *data, *dptr, val;
   C_uword size;
-  int maybe_fixnum = 0;
 
   /* vvv this can be taken out at a later stage (once it works reliably) vvv */
   if(bits != 0xfe)
@@ -8822,7 +8821,6 @@ static C_regparm C_word C_fcall decode_literal2(C_word **ptr, C_char **str,
 #else
     case (C_FLONUM_TYPE >> 24) & 0xff:
 #endif
-      maybe_fixnum = 1;
       bits = C_FLONUM_TYPE;
       break;
 
@@ -8841,19 +8839,24 @@ static C_regparm C_word C_fcall decode_literal2(C_word **ptr, C_char **str,
   val = (C_word)(*ptr);
 
   if(bits == C_FLONUM_TYPE) {
-    if(maybe_fixnum) {
-      long ln;
+    long ln;
+    double fn;
 
-      errno = 0;
-      ln = strtol(*str, str, 10);
+    switch (convert_string_to_number(*str, 10, &ln, &fn)) {
+    case 0: 			/* failed */
+      panic(C_text("invalid encoded numeric literal"));
+      break;
+
+    case 1:			/* fixnum */
+      val = C_fix(ln);
+      break;
 
-      if(((ln == LONG_MAX || ln == LONG_MIN) && errno == ERANGE) || **str != '\0')
-	val = C_number(ptr, C_strtod(*str, str));
-      else val = C_fix(ln);
+    case 2:			/* flonum */
+      val = C_flonum(ptr, fn);
+      break;
     }
-    else val = C_flonum(ptr, C_strtod(*str, str));
 
-    ++(*str);			/* skip terminating '\0' */
+    while(*((*str)++) != '\0');      /* skip terminating '\0' */
     return val;
   }
 
diff --git a/tests/compiler-tests.scm b/tests/compiler-tests.scm
index 226c440f..8edfe257 100644
--- a/tests/compiler-tests.scm
+++ b/tests/compiler-tests.scm
@@ -217,6 +217,10 @@
 
 (gp-test)
 
+;; Test that encode-literal/decode-literal use the proper functions
+;; to decode number literals.
+(assert (equal? '(+inf.0 -inf.0) (list (fp/ 1.0 0.0) (fp/ -1.0 0.0))))
+
 ;; Test that encode-literal doesn't drop digits for extreme flonum values.
 
 ;; This number is 2^971 * (2^53 - 1), and is the positive "all ones" number for
Trap