зеркало из https://github.com/mozilla/pjs.git
Bug 514575: Forbid rebinding 'eval' or 'arguments' in ES5 strict mode code. r=mrbkap
This commit is contained in:
Родитель
da2e0e1abf
Коммит
d2be6a745c
|
@ -316,3 +316,4 @@ MSG_DEF(JSMSG_STRICT_CODE_WITH, 233, 0, JSEXN_SYNTAXERR, "strict mode code
|
|||
MSG_DEF(JSMSG_DUPLICATE_PROPERTY, 234, 1, JSEXN_SYNTAXERR, "property name {0} appears more than once in object literal")
|
||||
MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 235, 0, JSEXN_SYNTAXERR, "Applying the 'delete' operator to an unqualified name is deprecated")
|
||||
MSG_DEF(JSMSG_DEPRECATED_ASSIGN, 236, 1, JSEXN_SYNTAXERR, "assignment to {0} is deprecated")
|
||||
MSG_DEF(JSMSG_BAD_BINDING, 237, 1, JSEXN_SYNTAXERR, "redefining {0} is deprecated")
|
||||
|
|
|
@ -257,6 +257,7 @@ struct JSTreeContext { /* tree context for semantic checks */
|
|||
#define TCF_NO_SCRIPT_RVAL 0x4000 /* API caller does not want result value
|
||||
from global script */
|
||||
#define TCF_HAS_SHARPS 0x8000 /* source contains sharp defs or uses */
|
||||
#define TCF_FUN_PARAM_EVAL 0x10000 /* function has parameter named 'eval' */
|
||||
|
||||
/*
|
||||
* Set when parsing a declaration-like destructuring pattern. This
|
||||
|
|
|
@ -1217,6 +1217,30 @@ CheckStrictAssignment(JSContext *cx, JSTreeContext *tc, JSParseNode *lhs)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that it is permitted to introduce a binding for atom. Strict
|
||||
* mode forbids introducing new definitions for 'eval' or 'arguments'.
|
||||
* Use pn for reporting error locations, or use tc's token stream if
|
||||
* pn is NULL.
|
||||
*/
|
||||
bool
|
||||
CheckStrictBinding(JSContext *cx, JSTreeContext *tc, JSAtom *atom,
|
||||
JSParseNode *pn)
|
||||
{
|
||||
if (!tc->needStrictChecks())
|
||||
return true;
|
||||
|
||||
JSAtomState *atomState = &cx->runtime->atomState;
|
||||
if (atom == atomState->evalAtom || atom == atomState->argumentsAtom) {
|
||||
const char *name = js_AtomToPrintableString(cx, atom);
|
||||
if (name)
|
||||
js_ReportStrictModeError(cx, TS(tc->compiler), tc, pn,
|
||||
JSMSG_BAD_BINDING, name);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* In strict mode code, all formal parameter names must be distinct. If fun's
|
||||
* formals are legit given fun's strictness level, return true. Otherwise,
|
||||
|
@ -1234,25 +1258,42 @@ static bool
|
|||
CheckStrictFormals(JSContext *cx, JSTreeContext *tc, JSFunction *fun,
|
||||
JSParseNode *pn)
|
||||
{
|
||||
JSAtom *atom;
|
||||
|
||||
if (!tc->needStrictChecks())
|
||||
return true;
|
||||
|
||||
JSAtom *dup = js_FindDuplicateFormal(fun);
|
||||
if (!dup)
|
||||
return true;
|
||||
atom = js_FindDuplicateFormal(fun);
|
||||
if (atom) {
|
||||
/*
|
||||
* We have found a duplicate parameter name. If we can find the
|
||||
* JSDefinition for the argument, that will have a more accurate source
|
||||
* location.
|
||||
*/
|
||||
JSDefinition *dn = ALE_DEFN(tc->decls.lookup(atom));
|
||||
if (dn->pn_op == JSOP_GETARG)
|
||||
pn = dn;
|
||||
const char *name = js_AtomToPrintableString(cx, atom);
|
||||
if (!name ||
|
||||
!js_ReportStrictModeError(cx, TS(tc->compiler), tc, pn,
|
||||
JSMSG_DUPLICATE_FORMAL, name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We have found a duplicate parameter name. If we can find the JSDefinition
|
||||
* for the argument, that will have a more accurate source location.
|
||||
*/
|
||||
JSDefinition *dn = ALE_DEFN(tc->decls.lookup(dup));
|
||||
if (dn->pn_op == JSOP_GETARG)
|
||||
pn = dn;
|
||||
const char *name = js_AtomToPrintableString(cx, dup);
|
||||
if (!name ||
|
||||
!js_ReportStrictModeError(cx, TS(tc->compiler), tc, pn,
|
||||
JSMSG_DUPLICATE_FORMAL, name)) {
|
||||
return false;
|
||||
if (tc->flags & (TCF_FUN_PARAM_ARGUMENTS | TCF_FUN_PARAM_EVAL)) {
|
||||
JSAtomState *atoms = &cx->runtime->atomState;
|
||||
atom = (tc->flags & TCF_FUN_PARAM_ARGUMENTS
|
||||
? atoms->argumentsAtom : atoms->evalAtom);
|
||||
/* The definition's source position will be more precise. */
|
||||
JSDefinition *dn = ALE_DEFN(tc->decls.lookup(atom));
|
||||
JS_ASSERT(dn->pn_atom == atom);
|
||||
const char *name = js_AtomToPrintableString(cx, atom);
|
||||
if (!name ||
|
||||
!js_ReportStrictModeError(cx, TS(tc->compiler), tc, dn,
|
||||
JSMSG_BAD_BINDING, name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1503,6 +1544,8 @@ DefineArg(JSParseNode *pn, JSAtom *atom, uintN i, JSTreeContext *tc)
|
|||
/* Flag tc so we don't have to lookup arguments on every use. */
|
||||
if (atom == tc->compiler->context->runtime->atomState.argumentsAtom)
|
||||
tc->flags |= TCF_FUN_PARAM_ARGUMENTS;
|
||||
if (atom == tc->compiler->context->runtime->atomState.evalAtom)
|
||||
tc->flags |= TCF_FUN_PARAM_EVAL;
|
||||
|
||||
/*
|
||||
* Make an argument definition node, distinguished by being in tc->decls
|
||||
|
@ -1691,6 +1734,8 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom,
|
|||
/* Flag tc so we don't have to lookup arguments on every use. */
|
||||
if (atom == tc->compiler->context->runtime->atomState.argumentsAtom)
|
||||
tc->flags |= TCF_FUN_PARAM_ARGUMENTS;
|
||||
if (atom == tc->compiler->context->runtime->atomState.evalAtom)
|
||||
tc->flags |= TCF_FUN_PARAM_EVAL;
|
||||
|
||||
JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
|
||||
ale = tc->decls.lookup(atom);
|
||||
|
@ -2821,6 +2866,9 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
if (!body)
|
||||
return NULL;
|
||||
|
||||
if (!CheckStrictBinding(cx, &funtc, funAtom, pn))
|
||||
return NULL;
|
||||
|
||||
if (!CheckStrictFormals(cx, &funtc, fun, pn))
|
||||
return NULL;
|
||||
|
||||
|
@ -3134,6 +3182,9 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
|
|||
JS_ASSERT(!tc->atTopLevel());
|
||||
|
||||
pn = data->pn;
|
||||
if (!CheckStrictBinding(cx, tc, atom, pn))
|
||||
return false;
|
||||
|
||||
blockObj = tc->blockChain;
|
||||
ale = tc->decls.lookup(atom);
|
||||
if (ale && ALE_DEFN(ale)->pn_blockid == tc->blockid()) {
|
||||
|
@ -3241,9 +3292,13 @@ OuterLet(JSTreeContext *tc, JSStmtInfo *stmt, JSAtom *atom)
|
|||
static JSBool
|
||||
BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
|
||||
{
|
||||
JSStmtInfo *stmt = js_LexicalLookup(tc, atom, NULL);
|
||||
JSParseNode *pn = data->pn;
|
||||
|
||||
if (!CheckStrictBinding(cx, tc, atom, pn))
|
||||
return false;
|
||||
|
||||
JSStmtInfo *stmt = js_LexicalLookup(tc, atom, NULL);
|
||||
|
||||
if (stmt && stmt->type == STMT_WITH) {
|
||||
pn->pn_op = JSOP_NAME;
|
||||
data->fresh = false;
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
/*
|
||||
* In strict mode, the identifier bound by a 'catch' clause may not
|
||||
* be 'eval' or 'arguments'.
|
||||
*/
|
||||
assertEq(testLenientAndStrict('try{}catch(eval){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('try{}catch([eval]){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('try{}catch({x:eval}){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('try{}catch(arguments){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('try{}catch([arguments]){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('try{}catch({x:arguments}){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
|
@ -0,0 +1,23 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
assertEq(testLenientAndStrict('var eval;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('var x,eval;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('var arguments;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('var x,arguments;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
|
@ -115,3 +115,298 @@ assertEq(testLenientAndStrict('(function (x,y) 2)',
|
|||
parsesSuccessfully,
|
||||
parsesSuccessfully),
|
||||
true);
|
||||
|
||||
/*
|
||||
* All permutations of:
|
||||
* - For the two magic identifiers 'arguments' or 'eval'
|
||||
* - For function definitions, function expressions, expression closures,
|
||||
* and getter and setter property definitions,
|
||||
* - For forms that inherit their context's strictness, and forms that
|
||||
* include their own strictness directives,
|
||||
* - For ordinary parameters, array destructuring parameters, and
|
||||
* object destructuring parameters,
|
||||
* - the magic identifiers may be used to name such parameters
|
||||
* in lenient code, but not in strict code
|
||||
* - the magic identifiers may be used as function names in lenient code,
|
||||
* but not in strict code
|
||||
*/
|
||||
assertEq(testLenientAndStrict('function f(eval){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f([eval]){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f({x:eval}){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function eval(){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f(eval){"use strict";}',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f([eval]){"use strict";}',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f({x:eval}){"use strict";}',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function eval(){"use strict";}',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f(eval){})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f([eval]){})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f({x:eval}){})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function eval(){})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f(eval){"use strict";})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f([eval]){"use strict";})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f({x:eval}){"use strict";})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function eval(){"use strict";})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f(eval) 2)',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f([eval]) 2)',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f({x:eval}) 2)',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function eval() 2)',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x(eval){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x([eval]){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x({x:eval}){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x(eval){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x([eval]){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x({x:eval}){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x(eval){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x([eval]){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x({x:eval}){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x(eval){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x([eval]){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x({x:eval}){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f(arguments){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f([arguments]){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f({x:arguments}){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function arguments(){}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f(arguments){"use strict";}',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f([arguments]){"use strict";}',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function f({x:arguments}){"use strict";}',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('function arguments(){"use strict";}',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f(arguments){})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f([arguments]){})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f({x:arguments}){})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function arguments(){})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f(arguments){"use strict";})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f([arguments]){"use strict";})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f({x:arguments}){"use strict";})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function arguments(){"use strict";})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f(arguments) 2)',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f([arguments]) 2)',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function f({x:arguments}) 2)',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(function arguments() 2)',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x(arguments){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x([arguments]){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x({x:arguments}){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x(arguments){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x([arguments]){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({get x({x:arguments}){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x(arguments){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x([arguments]){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x({x:arguments}){}})',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x(arguments){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x([arguments]){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('({set x({x:arguments}){"use strict";}})',
|
||||
parseRaisesException(SyntaxError),
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
/*
|
||||
* Functions produced using the Function constructor may not use
|
||||
* 'eval' or 'arguments' as a parameter name if their body is strict
|
||||
* mode code. The strictness of the calling code does not affect the
|
||||
* constraints applied to the parameters.
|
||||
*/
|
||||
assertEq(testLenientAndStrict('Function("eval","")',
|
||||
completesNormally,
|
||||
completesNormally),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('Function("eval","\'use strict\';")',
|
||||
raisesException(SyntaxError),
|
||||
raisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('Function("arguments","")',
|
||||
completesNormally,
|
||||
completesNormally),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('Function("arguments","\'use strict\';")',
|
||||
raisesException(SyntaxError),
|
||||
raisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@ script 11.4.4.js
|
|||
script 11.4.5.js
|
||||
script 11.13.1.js
|
||||
script 11.13.2.js
|
||||
script 12.2.1.js
|
||||
script 12.10.1.js
|
||||
script 12.14.1.js
|
||||
script 13.1.js
|
||||
script B.1.1.js
|
||||
script B.1.2.js
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
/*
|
||||
* In strict mode code, 'let' and 'const' declarations may not bind
|
||||
* 'eval' or 'arguments'.
|
||||
*/
|
||||
assertEq(testLenientAndStrict('let eval;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('let x,eval;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('let arguments;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('let x,arguments;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('const eval;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('const x,eval;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('const arguments;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('const x,arguments;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
/*
|
||||
* In strict mode code, 'let' declarations appearing in 'for'
|
||||
* or 'for in' statements may not bind 'eval' or 'arguments'.
|
||||
*/
|
||||
assertEq(testLenientAndStrict('for (let eval in [])break;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('for (let [eval] in [])break;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('for (let {x:eval} in [])break;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('for (let arguments in [])break;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('for (let [arguments] in [])break;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('for (let {x:arguments} in [])break;',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
/*
|
||||
* In strict mode, generator expressions may not locally bind 'eval'
|
||||
* or 'arguments.'
|
||||
*/
|
||||
assertEq(testLenientAndStrict('(1 for (eval in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(1 for ([eval] in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(1 for ({x:eval} in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(1 for (arguments in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(1 for ([arguments] in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('(1 for ({x:arguments} in []))',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
|
@ -1,2 +1,5 @@
|
|||
url-prefix ../../jsreftest.html?test=js1_8_1/strict/
|
||||
script 8.7.2.js
|
||||
script 12.2.1.js
|
||||
script generator-eval-arguments.js
|
||||
script let-block-eval-arguments.js
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
/* In strict mode, a 'let' block may not bind 'eval' or 'arguments'. */
|
||||
assertEq(testLenientAndStrict('let (eval=1) {}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('let ([eval]=1) {}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('let ({x:eval}=1) {}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('let (arguments=1) {}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('let ([arguments]=1) {}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict('let ({x:arguments}=1) {}',
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
Загрузка…
Ссылка в новой задаче