mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 907958 - Disallow |function function() {}| and similar unreadabilities. r=jorendorff, r=wingo for the yield interactions, r=luke for the asm.js interactions
This commit is contained in:
parent
adc074bd27
commit
38577c2633
@ -1642,7 +1642,7 @@ Parser<ParseHandler>::functionArguments(FunctionSyntaxKind kind, Node *listp, No
|
||||
#endif /* JS_HAS_DESTRUCTURING */
|
||||
|
||||
case TOK_YIELD:
|
||||
if (!checkYieldNameValidity(JSMSG_MISSING_FORMAL))
|
||||
if (!checkYieldNameValidity())
|
||||
return false;
|
||||
goto TOK_NAME;
|
||||
|
||||
@ -1720,20 +1720,6 @@ Parser<ParseHandler>::functionArguments(FunctionSyntaxKind kind, Node *listp, No
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::checkFunctionName(HandlePropertyName funName)
|
||||
{
|
||||
if (pc->isStarGenerator() && funName == context->names().yield) {
|
||||
// The name of a named function expression is specified to be bound in
|
||||
// the outer context as if via "let". In an ES6 generator, "yield" is
|
||||
// not a valid name for a let-bound variable.
|
||||
report(ParseError, false, null(), JSMSG_RESERVED_ID, "yield");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
Parser<FullParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
|
||||
@ -1746,9 +1732,6 @@ Parser<FullParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
|
||||
/* Function statements add a binding to the enclosing scope. */
|
||||
bool bodyLevel = pc->atBodyLevel();
|
||||
|
||||
if (!checkFunctionName(funName))
|
||||
return false;
|
||||
|
||||
if (kind == Statement) {
|
||||
/*
|
||||
* Handle redeclaration and optimize cases where we can statically bind the
|
||||
@ -1940,9 +1923,6 @@ Parser<SyntaxParseHandler>::checkFunctionDefinition(HandlePropertyName funName,
|
||||
/* Function statements add a binding to the enclosing scope. */
|
||||
bool bodyLevel = pc->atBodyLevel();
|
||||
|
||||
if (!checkFunctionName(funName))
|
||||
return false;
|
||||
|
||||
if (kind == Statement) {
|
||||
/*
|
||||
* Handle redeclaration and optimize cases where we can statically bind the
|
||||
@ -2419,15 +2399,11 @@ Parser<SyntaxParseHandler>::moduleDecl()
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::checkYieldNameValidity(unsigned errorNumber)
|
||||
Parser<ParseHandler>::checkYieldNameValidity()
|
||||
{
|
||||
// In star generators and in JS >= 1.7, yield is a keyword.
|
||||
if (pc->isStarGenerator() || versionNumber() >= JSVERSION_1_7) {
|
||||
report(ParseError, false, null(), errorNumber);
|
||||
return false;
|
||||
}
|
||||
// Otherwise in strict mode, yield is a future reserved word.
|
||||
if (pc->sc->strict) {
|
||||
// In star generators and in JS >= 1.7, yield is a keyword. Otherwise in
|
||||
// strict mode, yield is a future reserved word.
|
||||
if (pc->isStarGenerator() || versionNumber() >= JSVERSION_1_7 || pc->sc->strict) {
|
||||
report(ParseError, false, null(), JSMSG_RESERVED_ID, "yield");
|
||||
return false;
|
||||
}
|
||||
@ -2445,16 +2421,20 @@ Parser<ParseHandler>::functionStmt()
|
||||
|
||||
RootedPropertyName name(context);
|
||||
GeneratorKind generatorKind = NotGenerator;
|
||||
TokenKind tt = tokenStream.getToken(TokenStream::KeywordIsName);
|
||||
TokenKind tt = tokenStream.getToken();
|
||||
|
||||
if (tt == TOK_MUL) {
|
||||
tokenStream.tell(&start);
|
||||
tt = tokenStream.getToken(TokenStream::KeywordIsName);
|
||||
tt = tokenStream.getToken();
|
||||
generatorKind = StarGenerator;
|
||||
}
|
||||
|
||||
if (tt == TOK_NAME) {
|
||||
name = tokenStream.currentName();
|
||||
} else if (tt == TOK_YIELD) {
|
||||
if (!checkYieldNameValidity())
|
||||
return null();
|
||||
name = tokenStream.currentName();
|
||||
} else {
|
||||
/* Unnamed function expressions are forbidden in statement context. */
|
||||
report(ParseError, false, null(), JSMSG_UNNAMED_FUNCTION_STMT);
|
||||
@ -2478,20 +2458,25 @@ Parser<ParseHandler>::functionExpr()
|
||||
TokenStream::Position start(keepAtoms);
|
||||
tokenStream.tell(&start);
|
||||
|
||||
RootedPropertyName name(context);
|
||||
GeneratorKind generatorKind = NotGenerator;
|
||||
TokenKind tt = tokenStream.getToken(TokenStream::KeywordIsName);
|
||||
TokenKind tt = tokenStream.getToken();
|
||||
|
||||
if (tt == TOK_MUL) {
|
||||
tokenStream.tell(&start);
|
||||
tt = tokenStream.getToken(TokenStream::KeywordIsName);
|
||||
tt = tokenStream.getToken();
|
||||
generatorKind = StarGenerator;
|
||||
}
|
||||
|
||||
if (tt == TOK_NAME)
|
||||
RootedPropertyName name(context);
|
||||
if (tt == TOK_NAME) {
|
||||
name = tokenStream.currentName();
|
||||
else
|
||||
} else if (tt == TOK_YIELD) {
|
||||
if (!checkYieldNameValidity())
|
||||
return null();
|
||||
name = tokenStream.currentName();
|
||||
} else {
|
||||
tokenStream.ungetToken();
|
||||
}
|
||||
|
||||
return functionDef(name, start, Normal, Expression, generatorKind);
|
||||
}
|
||||
@ -3570,7 +3555,7 @@ Parser<ParseHandler>::variables(ParseNodeKind kind, bool *psimple,
|
||||
|
||||
if (tt != TOK_NAME) {
|
||||
if (tt == TOK_YIELD) {
|
||||
if (!checkYieldNameValidity(JSMSG_NO_VARIABLE_NAME))
|
||||
if (!checkYieldNameValidity())
|
||||
return null();
|
||||
} else {
|
||||
if (tt != TOK_ERROR)
|
||||
@ -4882,7 +4867,7 @@ Parser<ParseHandler>::tryStatement()
|
||||
#endif
|
||||
|
||||
case TOK_YIELD:
|
||||
if (!checkYieldNameValidity(JSMSG_CATCH_IDENTIFIER))
|
||||
if (!checkYieldNameValidity())
|
||||
return null();
|
||||
// Fall through.
|
||||
case TOK_NAME:
|
||||
|
@ -458,6 +458,11 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
||||
bool functionArgsAndBodyGeneric(Node pn, HandleFunction fun, FunctionType type,
|
||||
FunctionSyntaxKind kind, Directives *newDirectives);
|
||||
|
||||
// Determine whether |yield| is a valid name in the current context, or
|
||||
// whether it's prohibited due to strictness, JS version, or occurrence
|
||||
// inside a star generator.
|
||||
bool checkYieldNameValidity();
|
||||
|
||||
virtual bool strictMode() { return pc->sc->strict; }
|
||||
|
||||
const CompileOptions &options() const {
|
||||
@ -546,7 +551,6 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
||||
Node identifierName();
|
||||
|
||||
bool matchLabel(MutableHandle<PropertyName*> label);
|
||||
bool checkYieldNameValidity(unsigned errorNumber = JSMSG_SYNTAX_ERROR);
|
||||
|
||||
bool allowsForEachIn() {
|
||||
#if !JS_HAS_FOR_EACH_IN
|
||||
@ -568,7 +572,6 @@ class Parser : private AutoGCRooter, public StrictModeGetter
|
||||
|
||||
bool checkFunctionArguments();
|
||||
bool makeDefIntoUse(Definition *dn, Node pn, JSAtom *atom);
|
||||
bool checkFunctionName(HandlePropertyName funName);
|
||||
bool checkFunctionDefinition(HandlePropertyName funName, Node *pn, FunctionSyntaxKind kind,
|
||||
bool *pbodyProcessed);
|
||||
bool finishFunctionDefinition(Node pn, FunctionBox *funbox, Node prelude, Node body);
|
||||
|
@ -4588,10 +4588,18 @@ ParseFunction(ModuleCompiler &m, ParseNode **fnOut)
|
||||
DebugOnly<TokenKind> tk = tokenStream.getToken();
|
||||
JS_ASSERT(tk == TOK_FUNCTION);
|
||||
|
||||
if (tokenStream.getToken(TokenStream::KeywordIsName) != TOK_NAME)
|
||||
return false; // This will throw a SyntaxError, no need to m.fail.
|
||||
RootedPropertyName name(m.cx());
|
||||
|
||||
RootedPropertyName name(m.cx(), tokenStream.currentToken().name());
|
||||
TokenKind tt = tokenStream.getToken();
|
||||
if (tt == TOK_NAME) {
|
||||
name = tokenStream.currentName();
|
||||
} else if (tt == TOK_YIELD) {
|
||||
if (!m.parser().checkYieldNameValidity())
|
||||
return false;
|
||||
name = m.cx()->names().yield;
|
||||
} else {
|
||||
return false; // The regular parser will throw a SyntaxError, no need to m.fail.
|
||||
}
|
||||
|
||||
ParseNode *fn = m.parser().handler.newFunctionDefinition();
|
||||
if (!fn)
|
||||
|
@ -37,7 +37,7 @@ var strictFutureReservedWords =
|
||||
"yield", // enabled: this file doesn't execute as JS1.7
|
||||
];
|
||||
|
||||
function testWord(word, wordKind, expectNormal, expectStrict)
|
||||
function testWord(word, expectNormal, expectStrict)
|
||||
{
|
||||
var actual, status;
|
||||
|
||||
@ -355,22 +355,19 @@ function testWord(word, wordKind, expectNormal, expectStrict)
|
||||
|
||||
// USE AS FUNCTION NAME IN FUNCTION DECLARATION
|
||||
|
||||
if (wordKind !== "reserved")
|
||||
actual = "";
|
||||
status = summary + ": " + word + ": normal function name";
|
||||
try
|
||||
{
|
||||
actual = "";
|
||||
status = summary + ": " + word + ": normal function name";
|
||||
try
|
||||
{
|
||||
eval("function " + word + "() { }");
|
||||
actual = "no error";
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
actual = e.name;
|
||||
status += ", " + e.name + ": " + e.message + " ";
|
||||
}
|
||||
reportCompare(expectNormal, actual, status);
|
||||
eval("function " + word + "() { }");
|
||||
actual = "no error";
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
actual = e.name;
|
||||
status += ", " + e.name + ": " + e.message + " ";
|
||||
}
|
||||
reportCompare(expectNormal, actual, status);
|
||||
|
||||
actual = "";
|
||||
status = summary + ": " + word + ": strict function name";
|
||||
@ -402,22 +399,19 @@ function testWord(word, wordKind, expectNormal, expectStrict)
|
||||
|
||||
// USE AS FUNCTION NAME IN FUNCTION EXPRESSION
|
||||
|
||||
if (wordKind !== "reserved")
|
||||
actual = "";
|
||||
status = summary + ": " + word + ": normal function expression name";
|
||||
try
|
||||
{
|
||||
actual = "";
|
||||
status = summary + ": " + word + ": normal function expression name";
|
||||
try
|
||||
{
|
||||
eval("var s = (function " + word + "() { });");
|
||||
actual = "no error";
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
actual = e.name;
|
||||
status += ", " + e.name + ": " + e.message + " ";
|
||||
}
|
||||
reportCompare(expectNormal, actual, status);
|
||||
eval("var s = (function " + word + "() { });");
|
||||
actual = "no error";
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
actual = e.name;
|
||||
status += ", " + e.name + ": " + e.message + " ";
|
||||
}
|
||||
reportCompare(expectNormal, actual, status);
|
||||
|
||||
actual = "";
|
||||
status = summary + ": " + word + ": strict function expression name";
|
||||
@ -450,12 +444,12 @@ function testWord(word, wordKind, expectNormal, expectStrict)
|
||||
|
||||
function testFutureReservedWord(word)
|
||||
{
|
||||
testWord(word, "reserved", "SyntaxError", "SyntaxError");
|
||||
testWord(word, "SyntaxError", "SyntaxError");
|
||||
}
|
||||
|
||||
function testStrictFutureReservedWord(word)
|
||||
{
|
||||
testWord(word, "strict reserved", "no error", "SyntaxError");
|
||||
testWord(word, "no error", "SyntaxError");
|
||||
}
|
||||
|
||||
futureReservedWords.forEach(testFutureReservedWord);
|
||||
|
@ -1,49 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 343675;
|
||||
var summary = 'Allow keywords, reserved words as function names';
|
||||
var actual = '';
|
||||
var expect = 'No Error';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var words = [
|
||||
'break', 'else', 'new', 'var', 'case', 'finally', 'return', 'void',
|
||||
'catch', 'for', 'switch', 'while', 'continue', 'function', 'this',
|
||||
'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'do',
|
||||
'instanceof', 'typeof',
|
||||
'abstract', 'enum', 'int', 'short', 'boolean', 'export', 'interface',
|
||||
'static', 'byte', 'extends', 'long', 'super', 'char', 'final', 'native',
|
||||
'synchronized', 'class', 'float', 'package', 'throws', 'const', 'goto',
|
||||
'private', 'transient', 'debugger', 'implements', 'protected', 'volatile',
|
||||
'double', 'import', 'public'];
|
||||
|
||||
for (var i = 0; i < words.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
actual = 'No Error';
|
||||
eval('function ' + words[i] + '() {}');
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
}
|
||||
reportCompare(expect, actual, summary + ': ' + words[i]);
|
||||
}
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -93,17 +93,5 @@ function test()
|
||||
}
|
||||
reportCompare(expect, actual, summary + ': function () { var let;}');
|
||||
|
||||
try
|
||||
{
|
||||
expect = 'No Error';
|
||||
function yield() {}
|
||||
actual = 'No Error';
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
}
|
||||
reportCompare(expect, actual, summary + ': function yield()');
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
||||
|
@ -36,11 +36,7 @@ function test()
|
||||
|
||||
// Assertion failure: !pn->isPlaceholder(), at ../jsparse.cpp:4876
|
||||
// =====
|
||||
(function(){ var x; eval("var x; x = null"); })()
|
||||
|
||||
// Assertion failure: regs.sp == StackBase(fp), at ../jsinterp.cpp:2984
|
||||
// =====
|
||||
function this ({x}) { function x(){} }
|
||||
(function(){ var x; eval("var x; x = null"); })();
|
||||
|
||||
// Assertion failure: !(pnu->pn_dflags & PND_BOUND), at ../jsemit.cpp:1818
|
||||
// =====
|
||||
|
@ -111,7 +111,7 @@ ServerBSO.prototype = {
|
||||
return obj;
|
||||
},
|
||||
|
||||
delete: function delete() {
|
||||
delete: function delete_() {
|
||||
this.deleted = true;
|
||||
|
||||
delete this.payload;
|
||||
@ -571,7 +571,7 @@ StorageServerCollection.prototype = {
|
||||
return {success: success, failed: failed};
|
||||
},
|
||||
|
||||
delete: function delete(options) {
|
||||
delete: function delete_(options) {
|
||||
options = options || {};
|
||||
|
||||
// Protocol 2.0 only allows the "ids" query string argument.
|
||||
|
Loading…
Reference in New Issue
Block a user