/* * Any copyright is dedicated to the Public Domain. * http://creativecommons.org/licenses/publicdomain/ */ var gTestfile = 'strict-arguments.js'; var BUGNUMBER = 516255; var summary = "ES5 strict mode: arguments objects of strict mode functions must copy " + "argument values"; print(BUGNUMBER + ": " + summary); /************** * BEGIN TEST * **************/ function arrayEvery(arr, fun) { return Array.prototype.every.call(arr, fun); } function arraysEqual(a1, a2) { return a1.length === a2.length && arrayEvery(a1, function(v, i) { return v === a2[i]; }); } /************************ * NON-STRICT ARGUMENTS * ************************/ var obj = {}; function noargs() { return arguments; } assertEq(arraysEqual(noargs(), []), true); assertEq(arraysEqual(noargs(1), [1]), true); assertEq(arraysEqual(noargs(2, obj, 8), [2, obj, 8]), true); function args(a) { return arguments; } assertEq(arraysEqual(args(), []), true); assertEq(arraysEqual(args(1), [1]), true); assertEq(arraysEqual(args(1, obj), [1, obj]), true); assertEq(arraysEqual(args("foopy"), ["foopy"]), true); function assign(a) { a = 17; return arguments; } assertEq(arraysEqual(assign(1), [17]), true); function getLaterAssign(a) { var o = arguments; a = 17; return o; } assertEq(arraysEqual(getLaterAssign(1), [17]), true); function assignElementGetParameter(a) { arguments[0] = 17; return a; } assertEq(assignElementGetParameter(42), 17); function assignParameterGetElement(a) { a = 17; return arguments[0]; } assertEq(assignParameterGetElement(42), 17); function assignArgSub(x, y) { arguments[0] = 3; return arguments[0]; } assertEq(assignArgSub(1), 3); function assignArgSubParamUse(x, y) { arguments[0] = 3; assertEq(x, 3); return arguments[0]; } assertEq(assignArgSubParamUse(1), 3); function assignArgumentsElement(x, y) { arguments[0] = 3; return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations } assertEq(assignArgumentsElement(1), 3); function assignArgumentsElementParamUse(x, y) { arguments[0] = 3; assertEq(x, 3); return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations } assertEq(assignArgumentsElementParamUse(1), 3); /******************** * STRICT ARGUMENTS * ********************/ function strictNoargs() { "use strict"; return arguments; } assertEq(arraysEqual(strictNoargs(), []), true); assertEq(arraysEqual(strictNoargs(1), [1]), true); assertEq(arraysEqual(strictNoargs(1, obj), [1, obj]), true); function strictArgs(a) { "use strict"; return arguments; } assertEq(arraysEqual(strictArgs(), []), true); assertEq(arraysEqual(strictArgs(1), [1]), true); assertEq(arraysEqual(strictArgs(1, obj), [1, obj]), true); function strictAssign(a) { "use strict"; a = 17; return arguments; } assertEq(arraysEqual(strictAssign(), []), true); assertEq(arraysEqual(strictAssign(1), [1]), true); assertEq(arraysEqual(strictAssign(1, obj), [1, obj]), true); var upper; function strictAssignAfter(a) { "use strict"; upper = arguments; a = 42; return upper; } assertEq(arraysEqual(strictAssignAfter(), []), true); assertEq(arraysEqual(strictAssignAfter(17), [17]), true); assertEq(arraysEqual(strictAssignAfter(obj), [obj]), true); function strictMaybeAssignOuterParam(p) { "use strict"; function inner() { p = 17; } return arguments; } assertEq(arraysEqual(strictMaybeAssignOuterParam(), []), true); assertEq(arraysEqual(strictMaybeAssignOuterParam(42), [42]), true); assertEq(arraysEqual(strictMaybeAssignOuterParam(obj), [obj]), true); function strictAssignOuterParam(p) { "use strict"; function inner() { p = 17; } inner(); return arguments; } assertEq(arraysEqual(strictAssignOuterParam(), []), true); assertEq(arraysEqual(strictAssignOuterParam(17), [17]), true); assertEq(arraysEqual(strictAssignOuterParam(obj), [obj]), true); function strictAssignOuterParamPSYCH(p) { "use strict"; function inner(p) { p = 17; } inner(); return arguments; } assertEq(arraysEqual(strictAssignOuterParamPSYCH(), []), true); assertEq(arraysEqual(strictAssignOuterParamPSYCH(17), [17]), true); assertEq(arraysEqual(strictAssignOuterParamPSYCH(obj), [obj]), true); function strictEval(code, p) { "use strict"; eval(code); return arguments; } assertEq(arraysEqual(strictEval("1", 2), ["1", 2]), true); assertEq(arraysEqual(strictEval("arguments"), ["arguments"]), true); assertEq(arraysEqual(strictEval("p = 2"), ["p = 2"]), true); assertEq(arraysEqual(strictEval("p = 2", 17), ["p = 2", 17]), true); assertEq(arraysEqual(strictEval("arguments[0] = 17"), [17]), true); assertEq(arraysEqual(strictEval("arguments[0] = 17", 42), [17, 42]), true); function strictMaybeNestedEval(code, p) { "use strict"; function inner() { eval(code); } return arguments; } assertEq(arraysEqual(strictMaybeNestedEval("1", 2), ["1", 2]), true); assertEq(arraysEqual(strictMaybeNestedEval("arguments"), ["arguments"]), true); assertEq(arraysEqual(strictMaybeNestedEval("p = 2"), ["p = 2"]), true); assertEq(arraysEqual(strictMaybeNestedEval("p = 2", 17), ["p = 2", 17]), true); function strictNestedEval(code, p) { "use strict"; function inner() { eval(code); } inner(); return arguments; } assertEq(arraysEqual(strictNestedEval("1", 2), ["1", 2]), true); assertEq(arraysEqual(strictNestedEval("arguments"), ["arguments"]), true); assertEq(arraysEqual(strictNestedEval("p = 2"), ["p = 2"]), true); assertEq(arraysEqual(strictNestedEval("p = 2", 17), ["p = 2", 17]), true); assertEq(arraysEqual(strictNestedEval("arguments[0] = 17"), ["arguments[0] = 17"]), true); assertEq(arraysEqual(strictNestedEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true); function strictAssignArguments(a) { "use strict"; arguments[0] = 42; return a; } assertEq(strictAssignArguments(), undefined); assertEq(strictAssignArguments(obj), obj); assertEq(strictAssignArguments(17), 17); function strictAssignParameterGetElement(a) { "use strict"; a = 17; return arguments[0]; } assertEq(strictAssignParameterGetElement(42), 42); function strictAssignArgSub(x, y) { "use strict"; arguments[0] = 3; return arguments[0]; } assertEq(strictAssignArgSub(1), 3); function strictAssignArgSubParamUse(x, y) { "use strict"; arguments[0] = 3; assertEq(x, 1); return arguments[0]; } assertEq(strictAssignArgSubParamUse(1), 3); function strictAssignArgumentsElement(x, y) { "use strict"; arguments[0] = 3; return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations } assertEq(strictAssignArgumentsElement(1), 3); function strictAssignArgumentsElementParamUse(x, y) { "use strict"; arguments[0] = 3; assertEq(x, 1); return arguments[Math.random() ? "0" : 0]; // nix arguments[const] optimizations } assertEq(strictAssignArgumentsElementParamUse(1), 3); function strictNestedAssignShadowVar(p) { "use strict"; function inner() { var p = 12; function innermost() { p = 1776; return 12; } return innermost(); } return arguments; } assertEq(arraysEqual(strictNestedAssignShadowVar(), []), true); assertEq(arraysEqual(strictNestedAssignShadowVar(99), [99]), true); assertEq(arraysEqual(strictNestedAssignShadowVar(""), [""]), true); assertEq(arraysEqual(strictNestedAssignShadowVar(obj), [obj]), true); function strictNestedAssignShadowCatch(p) { "use strict"; function inner() { try { } catch (p) { var f = function innermost() { p = 1776; return 12; }; f(); } } return arguments; } assertEq(arraysEqual(strictNestedAssignShadowCatch(), []), true); assertEq(arraysEqual(strictNestedAssignShadowCatch(99), [99]), true); assertEq(arraysEqual(strictNestedAssignShadowCatch(""), [""]), true); assertEq(arraysEqual(strictNestedAssignShadowCatch(obj), [obj]), true); function strictNestedAssignShadowCatchCall(p) { "use strict"; function inner() { try { } catch (p) { var f = function innermost() { p = 1776; return 12; }; f(); } } inner(); return arguments; } assertEq(arraysEqual(strictNestedAssignShadowCatchCall(), []), true); assertEq(arraysEqual(strictNestedAssignShadowCatchCall(99), [99]), true); assertEq(arraysEqual(strictNestedAssignShadowCatchCall(""), [""]), true); assertEq(arraysEqual(strictNestedAssignShadowCatchCall(obj), [obj]), true); function strictNestedAssignShadowFunction(p) { "use strict"; function inner() { function p() { } p = 1776; } return arguments; } assertEq(arraysEqual(strictNestedAssignShadowFunction(), []), true); assertEq(arraysEqual(strictNestedAssignShadowFunction(99), [99]), true); assertEq(arraysEqual(strictNestedAssignShadowFunction(""), [""]), true); assertEq(arraysEqual(strictNestedAssignShadowFunction(obj), [obj]), true); function strictNestedAssignShadowFunctionCall(p) { "use strict"; function inner() { function p() { } p = 1776; } return arguments; } assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(), []), true); assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(99), [99]), true); assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(""), [""]), true); assertEq(arraysEqual(strictNestedAssignShadowFunctionCall(obj), [obj]), true); function strictNestedShadowAndMaybeEval(code, p) { "use strict"; function inner(p) { eval(code); } return arguments; } assertEq(arraysEqual(strictNestedShadowAndMaybeEval("1", 2), ["1", 2]), true); assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments"), ["arguments"]), true); assertEq(arraysEqual(strictNestedShadowAndMaybeEval("p = 2"), ["p = 2"]), true); assertEq(arraysEqual(strictNestedShadowAndMaybeEval("p = 2", 17), ["p = 2", 17]), true); assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments[0] = 17"), ["arguments[0] = 17"]), true); assertEq(arraysEqual(strictNestedShadowAndMaybeEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true); function strictNestedShadowAndEval(code, p) { "use strict"; function inner(p) { eval(code); } return arguments; } assertEq(arraysEqual(strictNestedShadowAndEval("1", 2), ["1", 2]), true); assertEq(arraysEqual(strictNestedShadowAndEval("arguments"), ["arguments"]), true); assertEq(arraysEqual(strictNestedShadowAndEval("p = 2"), ["p = 2"]), true); assertEq(arraysEqual(strictNestedShadowAndEval("p = 2", 17), ["p = 2", 17]), true); assertEq(arraysEqual(strictNestedShadowAndEval("arguments[0] = 17"), ["arguments[0] = 17"]), true); assertEq(arraysEqual(strictNestedShadowAndEval("arguments[0] = 17", 42), ["arguments[0] = 17", 42]), true); function strictEvalContainsMutation(code) { "use strict"; return eval(code); } assertEq(arraysEqual(strictEvalContainsMutation("code = 17; arguments"), ["code = 17; arguments"]), true); assertEq(arraysEqual(strictEvalContainsMutation("arguments[0] = 17; arguments"), [17]), true); assertEq(strictEvalContainsMutation("arguments[0] = 17; code"), "arguments[0] = 17; code"); function strictNestedAssignShadowFunctionName(p) { "use strict"; function inner() { function p() { p = 1776; } p(); } inner(); return arguments; } assertEq(arraysEqual(strictNestedAssignShadowFunctionName(), []), true); assertEq(arraysEqual(strictNestedAssignShadowFunctionName(99), [99]), true); assertEq(arraysEqual(strictNestedAssignShadowFunctionName(""), [""]), true); assertEq(arraysEqual(strictNestedAssignShadowFunctionName(obj), [obj]), true); /******************************************************************************/ if (typeof reportCompare === "function") reportCompare(true, true); print("All tests passed!");