Bug 1020420 part 4 - Make StringToNumber work with Latin1 strings. r=njn

This commit is contained in:
Jan de Mooij 2014-06-06 11:17:52 +02:00
Родитель 041e159bf3
Коммит 89492f5b1a
2 изменённых файлов: 34 добавлений и 7 удалений

Просмотреть файл

@ -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();

Просмотреть файл

@ -1476,11 +1476,12 @@ js::NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb)
return sb.appendInflated(cstr, cstrlen); return sb.appendInflated(cstr, cstrlen);
} }
template <typename CharT>
static bool 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) { if (length == 1) {
jschar c = chars[0]; CharT c = chars[0];
if ('0' <= c && c <= '9') if ('0' <= c && c <= '9')
*result = c - '0'; *result = c - '0';
else if (unicode::IsSpace(c)) else if (unicode::IsSpace(c))
@ -1490,8 +1491,8 @@ CharsToNumber(ThreadSafeContext *cx, const jschar *chars, size_t length, double
return true; return true;
} }
const jschar *end = chars + length; const CharT *end = chars + length;
const jschar *bp = SkipSpace(chars, end); const CharT *bp = SkipSpace(chars, end);
/* ECMA doesn't allow signed hex numbers (bug 273467). */ /* ECMA doesn't allow signed hex numbers (bug 273467). */
if (end - bp >= 2 && bp[0] == '0' && (bp[1] == 'x' || bp[1] == 'X')) { 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 * digit after the 0x, and if no non-whitespace characters follow all
* the hex digits. * the hex digits.
*/ */
const jschar *endptr; const CharT *endptr;
double d; double d;
if (!GetPrefixInteger(cx, bp + 2, end, 16, &endptr, &d) || if (!GetPrefixInteger(cx, bp + 2, end, 16, &endptr, &d) ||
endptr == bp + 2 || 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 * that have made it here (which can only be negative ones) will
* be treated as 0 without consuming the 'x' by js_strtod. * be treated as 0 without consuming the 'x' by js_strtod.
*/ */
const jschar *ep; const CharT *ep;
double d; double d;
if (!js_strtod(cx, bp, end, &ep, &d)) { if (!js_strtod(cx, bp, end, &ep, &d)) {
*result = GenericNaN(); *result = GenericNaN();
@ -1543,7 +1544,9 @@ js::StringToNumber(ThreadSafeContext *cx, JSString *str, double *result)
if (!inspector.ensureChars(cx, nogc)) if (!inspector.ensureChars(cx, nogc))
return false; 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 bool