~ chicken-core (chicken-5) 09df24b94a117d865910bd7a3d93f452a74af68d
commit 09df24b94a117d865910bd7a3d93f452a74af68d
Author: Peter Bex <peter.bex@xs4all.nl>
AuthorDate: Sun Sep 18 18:15:13 2011 +0200
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Wed Sep 21 10:30:01 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
Signed-off-by: felix <felix@call-with-current-continuation.org>
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