From d5237f4eaaf569706675693d3a6a8d7449303ae6 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 13 Aug 2021 02:31:41 -0700 Subject: int-str: 0x bug. * lib.c (int_str): The problem here is that we are recognizing and skipping the 0x prefix for all bases. So for instance (int-str "0x123") produces 123. The correct requirement, and the intent of the code, is that the C conventions are only honored if the base is specified as the character #\c. In any other base, including omitted base defaulting to 10, a leading zero is just a leading zero, and 0x is a zero followed by the junk character x. Therefore, if we have any valid base that isn't #\c, and 0x has been seen, we must return zero. We must not do this only in the base 16 case. * tests/016/conv.tl: New file. --- lib.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lib.c') diff --git a/lib.c b/lib.c index 79b3c1e4..18644a90 100644 --- a/lib.c +++ b/lib.c @@ -5745,15 +5745,16 @@ val int_str(val str, val base) if (base == chr('c')) { b = (zerox ? 16 : (octzero ? 8 : 10)); - } else if (b == 16) { - /* If base is 16, strtoul and its siblings - still recognize the 0x prefix. We don't want that; - except if base is the character #\c. Otherwise, - it is a zero with trailing junk. */ - if (zerox) - return zero; } else if (b < 2 || b > 36) { uw_throwf(error_s, lit("~a: invalid base ~s"), self, base, nao); + } else if (zerox) { + /* If we have a 0x prefix, and base is not #\c + * then that is just a zero followed by junk. + * We do this check here because wcstol recognizes + * these prefixes even when base isn't zero. + */ + if (zerox) + return zero; } /* TODO: detect if we have wcstoll */ -- cgit v1.2.3