ref: 60bde0ada44a1542b487ff98711c8d19a8c2a880
parent: 7d698ae9230261310d869188737366f1d5939490
author: Tor Andersson <tor@ccxvii.net>
date: Tue Feb 11 10:26:29 EST 2014
Improve jsV_stringtonumber. Tolerate leading and trailing whitespace, and hexadecimals. Return NAN if there is trailing garbage or errors.
--- a/jsbuiltin.c
+++ b/jsbuiltin.c
@@ -44,6 +44,7 @@
{
const char *s = js_tostring(J, 1);
double radix = js_isdefined(J, 2) ? js_tonumber(J, 2) : 10;
+ while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s;
js_pushnumber(J, strtol(s, NULL, radix == 0 ? 10 : radix));
return 1;
}
@@ -51,6 +52,7 @@
static int jsB_parseFloat(js_State *J, int argc)
{
const char *s = js_tostring(J, 1);
+ while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s;
js_pushnumber(J, strtod(s, NULL));
return 1;
}
--- a/jsvalue.c
+++ b/jsvalue.c
@@ -1,4 +1,5 @@
#include "jsi.h"
+#include "jslex.h"
#include "jscompile.h"
#include "jsvalue.h"
#include "utf.h"
@@ -113,8 +114,16 @@
/* ToNumber() on a string */
double jsV_stringtonumber(js_State *J, const char *s)
{
- /* TODO: use lexer to parse string grammar */
- return strtod(s, NULL);
+ char *e;
+ double n;
+ while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s;
+ if (s[0] == '0' && s[1] == 'x' && s[2] != 0)
+ n = strtol(s + 2, &e, 16);
+ else
+ n = strtod(s, &e);
+ while (jsY_iswhite(*e) || jsY_isnewline(*e)) ++e;
+ if (*e) return NAN;
+ return n;
}
/* ToNumber() on a value */