diff options
author | Mike Pall <mike> | 2018-04-22 13:14:28 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2018-04-22 13:14:28 +0200 |
commit | f3cf0d6e15240098147437fed7bd436ff55fdf8c (patch) | |
tree | 6c7ff1c79b0bbd9c0be6eb1bd3cd7841607a376b | |
parent | fe651bf6e2b4d02b624be3c289378c08bab2fa9b (diff) | |
download | luajit-f3cf0d6e15240098147437fed7bd436ff55fdf8c.tar.gz luajit-f3cf0d6e15240098147437fed7bd436ff55fdf8c.tar.bz2 luajit-f3cf0d6e15240098147437fed7bd436ff55fdf8c.zip |
Give expected results for negative non-base-10 numbers in tonumber().
This was undefined in Lua 5.1, but it's defined in 5.2.
-rw-r--r-- | src/lib_base.c | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/src/lib_base.c b/src/lib_base.c index 3a757870..d61e8762 100644 --- a/src/lib_base.c +++ b/src/lib_base.c | |||
@@ -287,18 +287,27 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) | |||
287 | } else { | 287 | } else { |
288 | const char *p = strdata(lj_lib_checkstr(L, 1)); | 288 | const char *p = strdata(lj_lib_checkstr(L, 1)); |
289 | char *ep; | 289 | char *ep; |
290 | unsigned int neg = 0; | ||
290 | unsigned long ul; | 291 | unsigned long ul; |
291 | if (base < 2 || base > 36) | 292 | if (base < 2 || base > 36) |
292 | lj_err_arg(L, 2, LJ_ERR_BASERNG); | 293 | lj_err_arg(L, 2, LJ_ERR_BASERNG); |
293 | ul = strtoul(p, &ep, base); | 294 | while (lj_char_isspace((unsigned char)(*p))) p++; |
294 | if (p != ep) { | 295 | if (*p == '-') { p++; neg = 1; } else if (*p == '+') { p++; } |
295 | while (lj_char_isspace((unsigned char)(*ep))) ep++; | 296 | if (lj_char_isalnum((unsigned char)(*p))) { |
296 | if (*ep == '\0') { | 297 | ul = strtoul(p, &ep, base); |
297 | if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u)) | 298 | if (p != ep) { |
298 | setintV(L->base-1-LJ_FR2, (int32_t)ul); | 299 | while (lj_char_isspace((unsigned char)(*ep))) ep++; |
299 | else | 300 | if (*ep == '\0') { |
300 | setnumV(L->base-1-LJ_FR2, (lua_Number)ul); | 301 | if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) { |
301 | return FFH_RES(1); | 302 | if (neg) ul = -ul; |
303 | setintV(L->base-1-LJ_FR2, (int32_t)ul); | ||
304 | } else { | ||
305 | lua_Number n = (lua_Number)ul; | ||
306 | if (neg) n = -n; | ||
307 | setnumV(L->base-1-LJ_FR2, n); | ||
308 | } | ||
309 | return FFH_RES(1); | ||
310 | } | ||
302 | } | 311 | } |
303 | } | 312 | } |
304 | } | 313 | } |