From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../adding-global-var-nonextensible-error.js | 36 +++++ js/src/tests/non262/global/browser.js | 0 js/src/tests/non262/global/bug-320887.js | 15 ++ js/src/tests/non262/global/bug660612.js | 7 + .../non262/global/cross-global-implicit-this.js | 84 ++++++++++ .../non262/global/decodeURI-decodes-FFFE-FFFF.js | 26 ++++ .../non262/global/delete-global-NaN-property.js | 32 ++++ js/src/tests/non262/global/direct-eval-but-not.js | 32 ++++ js/src/tests/non262/global/eval-01.js | 38 +++++ js/src/tests/non262/global/eval-02.js | 38 +++++ .../eval-in-strict-eval-in-normal-function.js | 30 ++++ .../non262/global/eval-inside-with-is-direct.js | 28 ++++ .../global/eval-native-callback-is-indirect.js | 32 ++++ .../tests/non262/global/globalThis-enumeration.js | 5 + .../non262/global/parenthesized-eval-is-direct.js | 68 +++++++++ js/src/tests/non262/global/parseFloat-01.js | 24 +++ js/src/tests/non262/global/parseInt-01.js | 170 +++++++++++++++++++++ .../non262/global/parseInt-default-to-decimal.js | 31 ++++ js/src/tests/non262/global/shell.js | 0 19 files changed, 696 insertions(+) create mode 100644 js/src/tests/non262/global/adding-global-var-nonextensible-error.js create mode 100644 js/src/tests/non262/global/browser.js create mode 100644 js/src/tests/non262/global/bug-320887.js create mode 100644 js/src/tests/non262/global/bug660612.js create mode 100644 js/src/tests/non262/global/cross-global-implicit-this.js create mode 100644 js/src/tests/non262/global/decodeURI-decodes-FFFE-FFFF.js create mode 100644 js/src/tests/non262/global/delete-global-NaN-property.js create mode 100644 js/src/tests/non262/global/direct-eval-but-not.js create mode 100644 js/src/tests/non262/global/eval-01.js create mode 100644 js/src/tests/non262/global/eval-02.js create mode 100644 js/src/tests/non262/global/eval-in-strict-eval-in-normal-function.js create mode 100644 js/src/tests/non262/global/eval-inside-with-is-direct.js create mode 100644 js/src/tests/non262/global/eval-native-callback-is-indirect.js create mode 100644 js/src/tests/non262/global/globalThis-enumeration.js create mode 100644 js/src/tests/non262/global/parenthesized-eval-is-direct.js create mode 100644 js/src/tests/non262/global/parseFloat-01.js create mode 100644 js/src/tests/non262/global/parseInt-01.js create mode 100644 js/src/tests/non262/global/parseInt-default-to-decimal.js create mode 100644 js/src/tests/non262/global/shell.js (limited to 'js/src/tests/non262/global') diff --git a/js/src/tests/non262/global/adding-global-var-nonextensible-error.js b/js/src/tests/non262/global/adding-global-var-nonextensible-error.js new file mode 100644 index 0000000000..fd5ab13edb --- /dev/null +++ b/js/src/tests/non262/global/adding-global-var-nonextensible-error.js @@ -0,0 +1,36 @@ +// |reftest| skip-if(!xulRuntime.shell) -- preventExtensions on global +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 621432; +var summary = + "If a var statement can't create a global property because the global " + + "object isn't extensible, and an error is thrown while decompiling the " + + "global, don't assert"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var toSource = []; +Object.preventExtensions(this); + +try +{ + eval("var x;"); + throw new Error("no error thrown"); +} +catch (e) +{ + reportCompare(e instanceof TypeError, true, "expected TypeError, got: " + e); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/global/browser.js b/js/src/tests/non262/global/browser.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/js/src/tests/non262/global/bug-320887.js b/js/src/tests/non262/global/bug-320887.js new file mode 100644 index 0000000000..5e8d3445ab --- /dev/null +++ b/js/src/tests/non262/global/bug-320887.js @@ -0,0 +1,15 @@ +// `var x` should not call the getter of an existing global property. + +var hit = 0; +Object.defineProperty(this, "x", { + get: function () { return ++hit; }, + configurable: true +}); +eval("var x;"); +assertEq(hit, 0); + +// The declaration should not have redefined the global x, either. +assertEq(x, 1); +assertEq(x, 2); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/global/bug660612.js b/js/src/tests/non262/global/bug660612.js new file mode 100644 index 0000000000..71589f53df --- /dev/null +++ b/js/src/tests/non262/global/bug660612.js @@ -0,0 +1,7 @@ +try { + decodeURIComponent('%ED%A0%80'); + assertEq(true, false, "expected an URIError"); +} catch (e) { + assertEq(e instanceof URIError, true); + reportCompare(true,true); +} diff --git a/js/src/tests/non262/global/cross-global-implicit-this.js b/js/src/tests/non262/global/cross-global-implicit-this.js new file mode 100644 index 0000000000..90c6e8a958 --- /dev/null +++ b/js/src/tests/non262/global/cross-global-implicit-this.js @@ -0,0 +1,84 @@ +// |reftest| skip-if(!xulRuntime.shell) -- needs evaluate() +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 671947; +var summary = "Unqualified function invocation uses the global object of the called property as |this|"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +this.name = "o"; + +function f() { + return this ? this.name : "t"; +} +function g() { + "use strict"; + return this ? this.name : "u"; +} +function h() { + return this ? this.name : "v"; +} + +var sb = newGlobal(); +sb.parent = this; +sb.name = "i"; +sb.f = f; +sb.g = g; + +sb.evaluate( + '\n' + + ' this.a = { name: "a", f: f, g: g };\n' + + ' this.b = { name: "b", f: f, g: g };\n' + + ' Object.defineProperty(this, "h", { get: (function(){ return parent.h; })});\n' + + ' Object.defineProperty(a, "h", { get: (function(){ return parent.h; })});\n' + + ' Object.defineProperty(b, "h", { get: (function(){ return parent.h; })});\n' + + ''); + + +// Three of the first four cases pass undefined (promoted inside the callee to +// the callee's global object). a.f() is the one exception, which passes the +// base, a, as the this object. +assertEq(sb.evaluate('(function(){return f();})();'), "o"); +assertEq(sb.evaluate('(function(){return (1,f)();})();'), "o"); +assertEq(sb.evaluate('(function(){return a.f();})();'), "a"); +assertEq(sb.evaluate('(function(){return eval("f()");})();'), "o"); + +// Same cases as above, but wrapped in a with. The first and last of these cases +// pass b, the object scoped by the with, as the this value. a.f() still passes +// the explicit base, a. (1,f)() is a little tricksier - this passes undefined +// (promoted to the callee global object) since the comma operator calls +// GetValue on the reference (see ES5 11.14.). +assertEq(sb.evaluate('(function(){with(b){ return (function(){ return f();})(); }})();'), "b"); +assertEq(sb.evaluate('(function(){with(b){ return (function(){ return (1,f)();})(); }})();'), "o"); +assertEq(sb.evaluate('(function(){with(b){ return (function(){ return a.f();})(); }})();'), "a"); +assertEq(sb.evaluate('(function(){with(b){ return (function(){ return eval("f()");})(); }})();'), "b"); + +// Same tests as above, but with a strict callee. We expect the same results, +// except undefined this is not replaced with the global object. +assertEq(sb.evaluate('(function(){return g();})();'), "u"); +assertEq(sb.evaluate('(function(){return (1,g)();})();'), "u"); +assertEq(sb.evaluate('(function(){return a.g();})();'), "a"); +assertEq(sb.evaluate('(function(){return eval("g()");})();'), "u"); +assertEq(sb.evaluate('(function(){with(b){ return g(); }})();'), "b"); +assertEq(sb.evaluate('(function(){with(b){ return (1,g)(); }})();'), "u"); +assertEq(sb.evaluate('(function(){with(b){ return a.g(); }})();'), "a"); +assertEq(sb.evaluate('(function(){with(b){ return (function(){ return eval("g()");})(); }})();'), "b"); + +/* Same as the first set, but h is a getter property. */ +assertEq(sb.evaluate('(function(){return h();})();'), "o"); +assertEq(sb.evaluate('(function(){return (1,h)();})();'), "o"); +assertEq(sb.evaluate('(function(){return a.h();})();'), "a"); +assertEq(sb.evaluate('(function(){return eval("h()");})();'), "o"); +assertEq(sb.evaluate('(function(){with(b){ return h(); }})();'), "b"); +assertEq(sb.evaluate('(function(){with(b){ return (1,h)(); }})();'), "o"); +assertEq(sb.evaluate('(function(){with(b){ return a.h(); }})();'), "a"); +assertEq(sb.evaluate('(function(){with(b){ return (function(){ return eval("h()");})(); }})();'), "b"); + +if (typeof reportCompare === "function"); + reportCompare(true, true); diff --git a/js/src/tests/non262/global/decodeURI-decodes-FFFE-FFFF.js b/js/src/tests/non262/global/decodeURI-decodes-FFFE-FFFF.js new file mode 100644 index 0000000000..28f3019cda --- /dev/null +++ b/js/src/tests/non262/global/decodeURI-decodes-FFFE-FFFF.js @@ -0,0 +1,26 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 520095; +var summary = + "decodeURI{,Component} should return the specified character for " + + "'%EF%BF%BE' and '%EF%BF%BF', not return U+FFFD"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +assertEq(decodeURI("%EF%BF%BE"), "\uFFFE"); +assertEq(decodeURI("%EF%BF%BF"), "\uFFFF"); +assertEq(decodeURIComponent("%EF%BF%BE"), "\uFFFE"); +assertEq(decodeURIComponent("%EF%BF%BF"), "\uFFFF"); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/global/delete-global-NaN-property.js b/js/src/tests/non262/global/delete-global-NaN-property.js new file mode 100644 index 0000000000..6bce5c26d2 --- /dev/null +++ b/js/src/tests/non262/global/delete-global-NaN-property.js @@ -0,0 +1,32 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +"use strict" + +//----------------------------------------------------------------------------- +var BUGNUMBER = 649570; +var summary = "|delete window.NaN| should throw a TypeError"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var g = this, v = false; +try +{ + delete this.NaN; + throw new Error("no exception thrown"); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "Expected a TypeError, got: " + e); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/non262/global/direct-eval-but-not.js b/js/src/tests/non262/global/direct-eval-but-not.js new file mode 100644 index 0000000000..a34192b372 --- /dev/null +++ b/js/src/tests/non262/global/direct-eval-but-not.js @@ -0,0 +1,32 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 609256; +var summary = + "Don't crash doing a direct eval when eval doesn't resolve to an object " + + "(let alone the original eval function)"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var eval = ""; +try +{ + eval(); + throw new Error("didn't throw?"); +} +catch (e) +{ + assertEq(e instanceof TypeError, true); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/global/eval-01.js b/js/src/tests/non262/global/eval-01.js new file mode 100644 index 0000000000..50bb95ffdb --- /dev/null +++ b/js/src/tests/non262/global/eval-01.js @@ -0,0 +1,38 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var a = 9; +var global = this; + +function test() { + var a = 0; + + // direct eval sees local a + assertEq(eval('a+1'), 1); + assertEq(eval('eval("a+1")'), 1); + + // indirect: using a name other than 'eval' + var foo = eval; + assertEq(foo('a+1'), 10); + assertEq(eval('foo("a+1")'), 10); // outer eval is direct, inner foo("a+1") is indirect + + // indirect: qualified method call + assertEq(this.eval("a+1"), 10); + assertEq(global.eval("a+1"), 10); + var obj = {foo: eval, eval: eval}; + assertEq(obj.foo('a+1'), 10); + assertEq(obj.eval('a+1'), 10); + var name = "eval"; + assertEq(obj[name]('a+1'), 10); + assertEq([eval][0]('a+1'), 10); + + // indirect: not called from a CallExpression at all + assertEq(eval.call(undefined, 'a+1'), 10); + assertEq(eval.call(global, 'a+1'), 10); + assertEq(eval.apply(undefined, ['a+1']), 10); + assertEq(eval.apply(global, ['a+1']), 10); + assertEq(['a+1'].map(eval)[0], 10); +} + +test(); +reportCompare(0, 0); diff --git a/js/src/tests/non262/global/eval-02.js b/js/src/tests/non262/global/eval-02.js new file mode 100644 index 0000000000..e1a315949c --- /dev/null +++ b/js/src/tests/non262/global/eval-02.js @@ -0,0 +1,38 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var a = 9; + +function directArg(eval, s) { + var a = 1; + return eval(s); +} + +function directVar(f, s) { + var eval = f; + var a = 1; + return eval(s); +} + +function directWith(obj, s) { + var f; + with (obj) { + f = function () { + var a = 1; + return eval(s); + }; + } + return f(); +} + +// direct eval, even though 'eval' is an argument +assertEq(directArg(eval, 'a+1'), 2); + +// direct eval, even though 'eval' is a var +assertEq(directVar(eval, 'a+1'), 2); + +// direct eval, even though 'eval' is found via a with block +assertEq(directWith(this, 'a+1'), 2); +assertEq(directWith({eval: eval, a: -1000}, 'a+1'), 2); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/global/eval-in-strict-eval-in-normal-function.js b/js/src/tests/non262/global/eval-in-strict-eval-in-normal-function.js new file mode 100644 index 0000000000..00d76652dd --- /dev/null +++ b/js/src/tests/non262/global/eval-in-strict-eval-in-normal-function.js @@ -0,0 +1,30 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 620130; +var summary = + "Calls to eval with same code + varying strict mode of script containing " + + "eval == fail"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function t(code) { return eval(code); } + +assertEq(t("'use strict'; try { eval('with (5) 17'); } catch (e) { 'threw'; }"), + "threw"); +assertEq(t("try { eval('with (5) 17'); } catch (e) { 'threw'; }"), + 17); +assertEq(t("'use strict'; try { eval('with (5) 17'); } catch (e) { 'threw'; }"), + "threw"); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/global/eval-inside-with-is-direct.js b/js/src/tests/non262/global/eval-inside-with-is-direct.js new file mode 100644 index 0000000000..d5d66483e0 --- /dev/null +++ b/js/src/tests/non262/global/eval-inside-with-is-direct.js @@ -0,0 +1,28 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 601307; +var summary = "with (...) eval(...) is a direct eval"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var t = "global"; +function test() +{ + var t = "local"; + with ({}) + return eval("t"); +} +assertEq(test(), "local"); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/global/eval-native-callback-is-indirect.js b/js/src/tests/non262/global/eval-native-callback-is-indirect.js new file mode 100644 index 0000000000..bfc4a3489d --- /dev/null +++ b/js/src/tests/non262/global/eval-native-callback-is-indirect.js @@ -0,0 +1,32 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 604504; +var summary = "eval called from a native function is indirect"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var originalEval = eval; + +var global = this; +var directCheckCode = "this === global"; + +function testBound() +{ + var global = "psych!"; + var eval = originalEval.bind(undefined, directCheckCode); + assertEq(eval(), true); +} +testBound(); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/global/globalThis-enumeration.js b/js/src/tests/non262/global/globalThis-enumeration.js new file mode 100644 index 0000000000..ecd5029473 --- /dev/null +++ b/js/src/tests/non262/global/globalThis-enumeration.js @@ -0,0 +1,5 @@ +assertEq(Object.getOwnPropertyNames(this).includes('globalThis'), true); + +if (typeof reportCompare === "function") { + reportCompare(0, 0); +} diff --git a/js/src/tests/non262/global/parenthesized-eval-is-direct.js b/js/src/tests/non262/global/parenthesized-eval-is-direct.js new file mode 100644 index 0000000000..4154128658 --- /dev/null +++ b/js/src/tests/non262/global/parenthesized-eval-is-direct.js @@ -0,0 +1,68 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +print("(eval)(...) is a direct eval, (1, eval)() isn't, etc."); + +/************** + * BEGIN TEST * + **************/ + +/* + * Justification: + * + * https://mail.mozilla.org/pipermail/es5-discuss/2010-October/003724.html + * + * Note also bug 537673. + */ + +var t = "global"; + +function group() +{ + var t = "local"; + return (eval)("t"); +} +assertEq(group(), "local"); + +function groupAndComma() +{ + var t = "local"; + return (1, eval)("t"); +} +assertEq(groupAndComma(), "global"); + +function groupAndTrueTernary() +{ + var t = "local"; + return (true ? eval : null)("t"); +} +assertEq(groupAndTrueTernary(), "global"); + +function groupAndEmptyStringTernary() +{ + var t = "local"; + return ("" ? null : eval)("t"); +} +assertEq(groupAndEmptyStringTernary(), "global"); + +function groupAndZeroTernary() +{ + var t = "local"; + return (0 ? null : eval)("t"); +} +assertEq(groupAndZeroTernary(), "global"); + +function groupAndNaNTernary() +{ + var t = "local"; + return (0 / 0 ? null : eval)("t"); +} +assertEq(groupAndNaNTernary(), "global"); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/global/parseFloat-01.js b/js/src/tests/non262/global/parseFloat-01.js new file mode 100644 index 0000000000..089c0901ec --- /dev/null +++ b/js/src/tests/non262/global/parseFloat-01.js @@ -0,0 +1,24 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 613492; +var summary = "ES5 15.1.2.3 parseFloat(string)"; + +print(BUGNUMBER + ": " + summary); + +assertEq(parseFloat("Infinity"), Infinity); +assertEq(parseFloat("+Infinity"), Infinity); +assertEq(parseFloat("-Infinity"), -Infinity); + +assertEq(parseFloat("inf"), NaN); +assertEq(parseFloat("Inf"), NaN); +assertEq(parseFloat("infinity"), NaN); + +assertEq(parseFloat("nan"), NaN); +assertEq(parseFloat("NaN"), NaN); + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/global/parseInt-01.js b/js/src/tests/non262/global/parseInt-01.js new file mode 100644 index 0000000000..0417086697 --- /dev/null +++ b/js/src/tests/non262/global/parseInt-01.js @@ -0,0 +1,170 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 577536; +var summary = "ES5 15.1.2.2 parseInt(string, radix)"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var str, radix; +var upvar; + +/* 1. Let inputString be ToString(string). */ + +assertEq(parseInt({ toString: function() { return "17" } }, 10), 17); + +upvar = 0; +str = { get toString() { upvar++; return function() { upvar++; return "12345"; } } }; +assertEq(parseInt(str, 10), 12345); +assertEq(upvar, 2); + + +/* + * 2. Let S be a newly created substring of inputString consisting of the first + * character that is not a StrWhiteSpaceChar and all characters following + * that character. (In other words, remove leading white space.) + */ + +var ws = + ["\t", "\v", "\f", " ", "\xA0", "\uFEFF", + "\u2004", "\u3000", // a few Unicode whitespaces + "\r", "\n", "\u2028", "\u2029"]; + +str = "8675309"; +for (var i = 0, sz = ws.length; i < sz; i++) +{ + assertEq(parseInt(ws[i] + str, 10), 8675309); + for (var j = 0, sz = ws.length; j < sz; j++) + { + assertEq(parseInt(ws[i] + ws[j] + str, 10), 8675309, + ws[i].charCodeAt(0).toString(16) + ", " + + ws[j].charCodeAt(0).toString(16)); + } +} + + +/* + * 3. Let sign be 1. + * 4. If S is not empty and the first character of S is a minus sign -, let + * sign be −1. + */ +str = "5552368"; +assertEq(parseInt("-" + str, 10), -parseInt(str, 10)); +assertEq(parseInt(" -" + str, 10), -parseInt(str, 10)); +assertEq(parseInt("-", 10), NaN); +assertEq(parseInt("", 10), NaN); +assertEq(parseInt("-0", 10), -0); + + +/* + * 5. If S is not empty and the first character of S is a plus sign + or a + * minus sign -, then remove the first character from S. + */ +assertEq(parseInt("+12345", 10), 12345); +assertEq(parseInt(" +12345", 10), 12345); +assertEq(parseInt("-12345", 10), -12345); +assertEq(parseInt(" -12345", 10), -12345); + + +/* + * 6. Let R = ToInt32(radix). + */ + +upvar = ""; +str = + { toString: function() { if (!upvar) upvar = "string"; return "42"; } }; +radix = + { toString: function() { if (!upvar) upvar = "radix"; return "10"; } }; + +assertEq(parseInt(str, radix), 42); +assertEq(upvar, "string"); + +assertEq(parseInt("123", null), 123); +assertEq(parseInt("123", undefined), 123); +assertEq(parseInt("123", NaN), 123); +assertEq(parseInt("123", -0), 123); +assertEq(parseInt("10", 72057594037927950), 16); +assertEq(parseInt("10", -4294967292), 4); +assertEq(parseInt("0x10", 1e308), 16); +assertEq(parseInt("10", 1e308), 10); +assertEq(parseInt("10", { valueOf: function() { return 16; } }), 16); + + +/* + * 7. Let stripPrefix be true. + * 8. If R ≠ 0, then + * a. If R < 2 or R > 36, then return NaN. + * b. If R ≠ 16, let stripPrefix be false. + * 9. Else, R = 0 + * a. Let R = 10. + * 10. If stripPrefix is true, then + * a. If the length of S is at least 2 and the first two characters of S + * are either “0x” or “0X”, then remove the first two characters from S and + * let R = 16. + */ +var vs = ["1", "51", "917", "2343", "99963"]; +for (var i = 0, sz = vs.length; i < sz; i++) + assertEq(parseInt(vs[i], 0), parseInt(vs[i], 10), "bad " + vs[i]); + +assertEq(parseInt("0x10"), 16); +assertEq(parseInt("0x10", 0), 16); +assertEq(parseInt("0x10", 16), 16); +assertEq(parseInt("0x10", 8), 0); +assertEq(parseInt("-0x10", 16), -16); + +assertEq(parseInt("5", 1), NaN); +assertEq(parseInt("5", 37), NaN); +assertEq(parseInt("5", { valueOf: function() { return -1; } }), NaN); + + +/* + * 11. If S contains any character that is not a radix-R digit, then let Z be + * the substring of S consisting of all characters before the first such + * character; otherwise, let Z be S. + * 12. If Z is empty, return NaN. + */ +assertEq(parseInt(""), NaN); +assertEq(parseInt("ohai"), NaN); +assertEq(parseInt("0xohai"), NaN); +assertEq(parseInt("-ohai"), NaN); +assertEq(parseInt("+ohai"), NaN); +assertEq(parseInt(" ohai"), NaN); + +assertEq(parseInt("0xaohai"), 10); +assertEq(parseInt("hohai", 18), 17); + + +/* + * 13. Let mathInt be the mathematical integer value that is represented by Z + * in radix-R notation, using the letters A-Z and a-z for digits with + * values 10 through 35. (However, if R is 10 and Z contains more than 20 + * significant digits, every significant digit after the 20th may be + * replaced by a 0 digit, at the option of the implementation; and if R is + * not 2, 4, 8, 10, 16, or 32, then mathInt may be an implementation- + * dependent approximation to the mathematical integer value that is + * represented by Z in radix-R notation.) + * 14. Let number be the Number value for mathInt. + * 15. Return sign × number. + */ +assertEq(parseInt("ohai", 36), 1142154); +assertEq(parseInt("0ohai", 36), 1142154); +assertEq(parseInt("00ohai", 36), 1142154); +assertEq(parseInt("A", 16), 10); +assertEq(parseInt("0A", 16), 10); +assertEq(parseInt("00A", 16), 10); +assertEq(parseInt("A", 17), 10); +assertEq(parseInt("0A", 17), 10); +assertEq(parseInt("00A", 17), 10); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/global/parseInt-default-to-decimal.js b/js/src/tests/non262/global/parseInt-default-to-decimal.js new file mode 100644 index 0000000000..b2e1378a4f --- /dev/null +++ b/js/src/tests/non262/global/parseInt-default-to-decimal.js @@ -0,0 +1,31 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 583925; +var summary = + "parseInt should treat leading-zero inputs (with radix unspecified) as " + + "decimal, not octal (this changed in bug 786135)"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +assertEq(parseInt("08"), 8); +assertEq(parseInt("09"), 9); +assertEq(parseInt("014"), 14); + +function strictParseInt(s) { "use strict"; return parseInt(s); } + +assertEq(strictParseInt("08"), 8); +assertEq(strictParseInt("09"), 9); +assertEq(strictParseInt("014"), 14); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/global/shell.js b/js/src/tests/non262/global/shell.js new file mode 100644 index 0000000000..e69de29bb2 -- cgit v1.2.3