>From 96286a7a7144b17e4b7a3f08164fb6d6296f1722 Mon Sep 17 00:00:00 2001 From: Peter Bex Date: Sun, 18 Sep 2011 18:15:13 +0200 Subject: [PATCH] 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 --- runtime.c | 25 ++++++++++++++----------- tests/compiler-tests.scm | 4 ++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/runtime.c b/runtime.c index 5f8a0ca..13e16e2 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 226c440..8edfe25 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 -- 1.7.3.4