Bug 514575: Forbid rebinding 'eval' or 'arguments' in ES5 strict mode code. r=mrbkap

This commit is contained in:
Jim Blandy 2009-11-19 14:08:02 -08:00
Родитель da2e0e1abf
Коммит d2be6a745c
11 изменённых файлов: 570 добавлений и 16 удалений

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

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