From 89492f5b1abcd1c002cc55a1a6adb3a45f39f59a Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Fri, 6 Jun 2014 11:17:52 +0200 Subject: [PATCH] Bug 1020420 part 4 - Make StringToNumber work with Latin1 strings. r=njn --- js/src/jit-test/tests/latin1/toNumber.js | 24 ++++++++++++++++++++++++ js/src/jsnum.cpp | 17 ++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 js/src/jit-test/tests/latin1/toNumber.js diff --git a/js/src/jit-test/tests/latin1/toNumber.js b/js/src/jit-test/tests/latin1/toNumber.js new file mode 100644 index 000000000000..5cfa444ba52e --- /dev/null +++ b/js/src/jit-test/tests/latin1/toNumber.js @@ -0,0 +1,24 @@ +function testToNumber() { + // Latin1 + assertEq(+toLatin1("12345.6"), 12345.6); + assertEq(+toLatin1("+123"), 123); + assertEq(+toLatin1("0xABC"), 0xABC); + assertEq(+toLatin1("112."), 112); + assertEq(+toLatin1("112.A"), NaN); + assertEq(+toLatin1("-Infinity"), -Infinity); + + // TwoByte + function twoByte(s) { + s = "\u1200" + s; + s = s.substr(1); + assertEq(isLatin1(s), false); + return s; + } + assertEq(+twoByte("12345.6"), 12345.6); + assertEq(+twoByte("+123"), 123); + assertEq(+twoByte("0xABC"), 0xABC); + assertEq(+twoByte("112."), 112); + assertEq(+twoByte("112.A"), NaN); + assertEq(+twoByte("-Infinity"), -Infinity); +} +testToNumber(); diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index 6d0574c7b0fc..3cd1ddc8ca2e 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -1476,11 +1476,12 @@ js::NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb) return sb.appendInflated(cstr, cstrlen); } +template static bool -CharsToNumber(ThreadSafeContext *cx, const jschar *chars, size_t length, double *result) +CharsToNumber(ThreadSafeContext *cx, const CharT *chars, size_t length, double *result) { if (length == 1) { - jschar c = chars[0]; + CharT c = chars[0]; if ('0' <= c && c <= '9') *result = c - '0'; else if (unicode::IsSpace(c)) @@ -1490,8 +1491,8 @@ CharsToNumber(ThreadSafeContext *cx, const jschar *chars, size_t length, double return true; } - const jschar *end = chars + length; - const jschar *bp = SkipSpace(chars, end); + const CharT *end = chars + length; + const CharT *bp = SkipSpace(chars, end); /* ECMA doesn't allow signed hex numbers (bug 273467). */ if (end - bp >= 2 && bp[0] == '0' && (bp[1] == 'x' || bp[1] == 'X')) { @@ -1500,7 +1501,7 @@ CharsToNumber(ThreadSafeContext *cx, const jschar *chars, size_t length, double * digit after the 0x, and if no non-whitespace characters follow all * the hex digits. */ - const jschar *endptr; + const CharT *endptr; double d; if (!GetPrefixInteger(cx, bp + 2, end, 16, &endptr, &d) || endptr == bp + 2 || @@ -1520,7 +1521,7 @@ CharsToNumber(ThreadSafeContext *cx, const jschar *chars, size_t length, double * that have made it here (which can only be negative ones) will * be treated as 0 without consuming the 'x' by js_strtod. */ - const jschar *ep; + const CharT *ep; double d; if (!js_strtod(cx, bp, end, &ep, &d)) { *result = GenericNaN(); @@ -1543,7 +1544,9 @@ js::StringToNumber(ThreadSafeContext *cx, JSString *str, double *result) if (!inspector.ensureChars(cx, nogc)) return false; - return CharsToNumber(cx, inspector.twoByteChars(), str->length(), result); + return inspector.hasLatin1Chars() + ? CharsToNumber(cx, inspector.latin1Chars(), str->length(), result) + : CharsToNumber(cx, inspector.twoByteChars(), str->length(), result); } bool