diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-08-13 02:31:41 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-08-13 02:31:41 -0700 |
commit | d5237f4eaaf569706675693d3a6a8d7449303ae6 (patch) | |
tree | e1d85eba5c85209b8915c37f653111ec1c368055 /lib.c | |
parent | 2265d0cade2ee95f8a16273e66a7af3d05d34e85 (diff) | |
download | txr-d5237f4eaaf569706675693d3a6a8d7449303ae6.tar.gz txr-d5237f4eaaf569706675693d3a6a8d7449303ae6.tar.bz2 txr-d5237f4eaaf569706675693d3a6a8d7449303ae6.zip |
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.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 15 |
1 files changed, 8 insertions, 7 deletions
@@ -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 */ |