aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2018-04-22 13:14:28 +0200
committerMike Pall <mike>2018-04-22 13:14:28 +0200
commitf3cf0d6e15240098147437fed7bd436ff55fdf8c (patch)
tree6c7ff1c79b0bbd9c0be6eb1bd3cd7841607a376b
parentfe651bf6e2b4d02b624be3c289378c08bab2fa9b (diff)
downloadluajit-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.c27
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 }