зеркало из https://github.com/mozilla/pjs.git
Bug 609832: Function statements should be banned (for now) in ES5 strict mode. (r=cdleary)
This commit is contained in:
Родитель
fec1549ee2
Коммит
cd3e22e469
|
@ -346,3 +346,4 @@ MSG_DEF(JSMSG_CANT_WRAP_XML_OBJECT, 263, 0, JSEXN_TYPEERR, "can't wrap XML obj
|
|||
MSG_DEF(JSMSG_BAD_CLONE_VERSION, 264, 0, JSEXN_ERR, "unsupported structured clone version")
|
||||
MSG_DEF(JSMSG_CANT_CLONE_OBJECT, 265, 0, JSEXN_TYPEERR, "can't clone object")
|
||||
MSG_DEF(JSMSG_NON_NATIVE_SCOPE, 266, 0, JSEXN_TYPEERR, "non-native scope object")
|
||||
MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 267, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may only be declared at top level or immediately within another function")
|
||||
|
|
|
@ -3244,6 +3244,13 @@ Parser::functionStmt()
|
|||
}
|
||||
tokenStream.ungetToken();
|
||||
}
|
||||
|
||||
/* We forbid function statements in strict mode code. */
|
||||
if (!tc->atBodyLevel() && tc->inStrictMode()) {
|
||||
reportErrorNumber(NULL, JSREPORT_STRICT_MODE_ERROR, JSMSG_STRICT_FUNCTION_STATEMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return functionDef(name, GENERAL, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,3 +21,4 @@ script bug472534.js
|
|||
script bug496985.js
|
||||
script bug566661.js
|
||||
script iterator-in-catch.js
|
||||
script strict-function-statements.js
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
/* -*- 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/
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return true if both of these return true:
|
||||
* - LENIENT_PRED applied to CODE
|
||||
* - STRICT_PRED applied to CODE with a use strict directive added to the front
|
||||
*
|
||||
* Run STRICT_PRED first, for testing code that affects the global environment
|
||||
* in loose mode, but fails in strict mode.
|
||||
*/
|
||||
function testLenientAndStrict(code, lenient_pred, strict_pred) {
|
||||
return (strict_pred("'use strict'; " + code) &&
|
||||
lenient_pred(code));
|
||||
}
|
||||
|
||||
/*
|
||||
* raisesException(EXCEPTION)(CODE) returns true if evaluating CODE (as eval
|
||||
* code) throws an exception object whose prototype is
|
||||
* EXCEPTION.prototype, and returns false if it throws any other error
|
||||
* or evaluates successfully. For example: raises(TypeError)("0()") ==
|
||||
* true.
|
||||
*/
|
||||
function raisesException(exception) {
|
||||
return function (code) {
|
||||
try {
|
||||
eval(code);
|
||||
return false;
|
||||
} catch (actual) {
|
||||
return exception.prototype.isPrototypeOf(actual);
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
// Ordinary function definitions should be unaffected.
|
||||
assertEq(testLenientAndStrict("function f() { }",
|
||||
parsesSuccessfully,
|
||||
parsesSuccessfully),
|
||||
true);
|
||||
|
||||
// Function statements within blocks are forbidden in strict mode code.
|
||||
assertEq(testLenientAndStrict("{ function f() { } }",
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
// Lambdas are always permitted within blocks.
|
||||
assertEq(testLenientAndStrict("{ (function f() { }) }",
|
||||
parsesSuccessfully,
|
||||
parsesSuccessfully),
|
||||
true);
|
||||
|
||||
// Function statements within any sort of statement are forbidden in strict mode code.
|
||||
assertEq(testLenientAndStrict("if (true) function f() { }",
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict("while (true) function f() { }",
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict("do function f() { } while (true);",
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict("for(;;) function f() { }",
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict("for(x in []) function f() { }",
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict("with(o) function f() { }",
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict("switch(1) { case 1: function f() { } }",
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict("x: function f() { }",
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
assertEq(testLenientAndStrict("try { function f() { } } catch (x) { }",
|
||||
parsesSuccessfully,
|
||||
parseRaisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
// Lambdas are always permitted within any sort of statement.
|
||||
assertEq(testLenientAndStrict("if (true) (function f() { })",
|
||||
parsesSuccessfully,
|
||||
parsesSuccessfully),
|
||||
true);
|
||||
|
||||
// Function statements are permitted in blocks within lenient functions.
|
||||
assertEq(parsesSuccessfully("function f() { function g() { } }"),
|
||||
true);
|
||||
|
||||
// Function statements are permitted in any statement within lenient functions.
|
||||
assertEq(parsesSuccessfully("function f() { if (true) function g() { } }"),
|
||||
true);
|
||||
|
||||
assertEq(parseRaisesException(SyntaxError)
|
||||
("function f() { 'use strict'; if (true) function g() { } }"),
|
||||
true);
|
||||
|
||||
assertEq(parseRaisesException(SyntaxError)
|
||||
("function f() { 'use strict'; { function g() { } } }"),
|
||||
true);
|
||||
|
||||
assertEq(parsesSuccessfully("function f() { 'use strict'; if (true) (function g() { }) }"),
|
||||
true);
|
||||
|
||||
assertEq(parsesSuccessfully("function f() { 'use strict'; { (function g() { }) } }"),
|
||||
true);
|
||||
|
||||
// Eval should behave the same way. (The parse-only tests use the Function constructor.)
|
||||
assertEq(testLenientAndStrict("function f() { }",
|
||||
completesNormally,
|
||||
completesNormally),
|
||||
true);
|
||||
assertEq(testLenientAndStrict("{ function f() { } }",
|
||||
completesNormally,
|
||||
raisesException(SyntaxError)),
|
||||
true);
|
||||
|
||||
reportCompare(true, true);
|
Загрузка…
Ссылка в новой задаче