aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-04-12 09:18:04 +0200
committerLars Knoll <lars.knoll@qt.io>2018-04-25 17:50:33 +0000
commit9f731b6841bbc9b7425a95303369d05be895f949 (patch)
treeb3a34152a06f5066d0b60b4d0e3f30333e6c2d0e /src/qml
parente2ed846dd4710268a208962f3217b79994e8cb31 (diff)
Fix crashes when parsing some invalid JS
function foo() { let x; function x() {} } would crash. Throw an error instead now. Change-Id: I5e5588deb21c1777be15a6656baefc422d59ff0c Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp25
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions_p.h4
2 files changed, 14 insertions, 15 deletions
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp
index 5b7103323e..3f7211b95e 100644
--- a/src/qml/compiler/qv4compilerscanfunctions.cpp
+++ b/src/qml/compiler/qv4compilerscanfunctions.cpp
@@ -225,7 +225,8 @@ bool ScanFunctions::visit(ExpressionStatement *ast)
if (!_allowFuncDecls)
_cg->throwSyntaxError(expr->functionToken, QStringLiteral("conditional function or closure declaration"));
- enterFunction(expr, /*enterName*/ true);
+ if (!enterFunction(expr, /*enterName*/ true))
+ return false;
Node::accept(expr->formals, this);
Node::accept(expr->body, this);
leaveEnvironment();
@@ -241,8 +242,7 @@ bool ScanFunctions::visit(ExpressionStatement *ast)
bool ScanFunctions::visit(FunctionExpression *ast)
{
- enterFunction(ast, /*enterName*/ false);
- return true;
+ return enterFunction(ast, /*enterName*/ false);
}
bool ScanFunctions::visit(TemplateLiteral *ast)
@@ -256,11 +256,11 @@ bool ScanFunctions::visit(TemplateLiteral *ast)
}
-void ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName)
+bool ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName)
{
if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
_cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode"));
- enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : nullptr);
+ return enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : nullptr);
}
void ScanFunctions::endVisit(FunctionExpression *)
@@ -289,8 +289,7 @@ bool ScanFunctions::visit(ObjectLiteral *ast)
bool ScanFunctions::visit(PropertyGetterSetter *ast)
{
TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
- enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/nullptr);
- return true;
+ return enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/nullptr);
}
void ScanFunctions::endVisit(PropertyGetterSetter *)
@@ -300,8 +299,7 @@ void ScanFunctions::endVisit(PropertyGetterSetter *)
bool ScanFunctions::visit(FunctionDeclaration *ast)
{
- enterFunction(ast, /*enterName*/ true);
- return true;
+ return enterFunction(ast, /*enterName*/ true);
}
void ScanFunctions::endVisit(FunctionDeclaration *)
@@ -390,7 +388,7 @@ bool ScanFunctions::visit(Block *ast) {
return false;
}
-void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, FunctionExpression *expr)
+bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, FunctionExpression *expr)
{
Context *outerContext = _context;
enterEnvironment(ast, FunctionCode);
@@ -401,7 +399,7 @@ void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete
if (expr) {
if (!outerContext->addLocalVar(name, Context::FunctionDefinition, AST::VariableDeclaration::FunctionScope, expr)) {
_cg->throwSyntaxError(ast->firstSourceLocation(), QStringLiteral("Identifier %1 has already been declared").arg(name));
- return;
+ return false;
}
}
if (name == QLatin1String("arguments"))
@@ -430,18 +428,19 @@ void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete
bool duplicate = (boundNames.indexOf(arg, i + 1) != -1);
if (duplicate) {
_cg->throwSyntaxError(formals->firstSourceLocation(), QStringLiteral("Duplicate parameter name '%1' is not allowed.").arg(arg));
- return;
+ return false;
}
}
if (_context->isStrict) {
if (arg == QLatin1String("eval") || arg == QLatin1String("arguments")) {
_cg->throwSyntaxError(formals->firstSourceLocation(), QStringLiteral("'%1' cannot be used as parameter name in strict mode").arg(arg));
- return;
+ return false;
}
}
if (!_context->arguments.contains(arg))
_context->addLocalVar(arg, Context::VariableDefinition, QQmlJS::AST::VariableDeclaration::FunctionScope);
}
+ return true;
}
void ScanFunctions::calcEscapingVariables()
diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h
index 940bd9f73a..cf79da2203 100644
--- a/src/qml/compiler/qv4compilerscanfunctions_p.h
+++ b/src/qml/compiler/qv4compilerscanfunctions_p.h
@@ -111,7 +111,7 @@ protected:
bool visit(AST::FunctionExpression *ast) override;
bool visit(AST::TemplateLiteral *ast) override;
- void enterFunction(AST::FunctionExpression *ast, bool enterName);
+ bool enterFunction(AST::FunctionExpression *ast, bool enterName);
void endVisit(AST::FunctionExpression *) override;
@@ -136,7 +136,7 @@ protected:
bool visit(AST::Block *ast) override;
protected:
- void enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::StatementList *body, AST::FunctionExpression *expr);
+ bool enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::StatementList *body, AST::FunctionExpression *expr);
void calcEscapingVariables();
// fields: