aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 }