aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-10-15 14:09:55 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2018-10-18 07:40:39 +0000
commit5b39daf40d8d6dae7716b7161ee165e39ce02241 (patch)
treed101e31eb3158bf1be07566ed53aea9a3263653b
parent50924bd8557db9a398f3c1ccdd6996d968658b23 (diff)
JS: Fix stack buffer overflow in the QML/JS parser
Task-number: QTBUG-71083 Change-Id: I7a06a01871c2ae0b3162699189c4e836c36d7759 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/parser/qqmljs.g25
-rw-r--r--tests/auto/qml/v4misc/tst_v4misc.cpp1
2 files changed, 11 insertions, 15 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index a844e3cb3e..a7ae664d72 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -550,6 +550,8 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
void Parser::pushToken(int token)
{
+ Q_ASSERT(last_token);
+ Q_ASSERT(last_token < &token_buffer[TOKEN_BUFFER_SIZE]);
last_token->token = yytoken;
last_token->dval = yylval;
last_token->spell = yytokenspell;
@@ -4386,6 +4388,9 @@ ExportSpecifier: IdentifierName T_AS IdentifierName;
token_buffer[1].loc = yylloc = location(lexer);
if (t_action(errorState, yytoken)) {
+#ifdef PARSER_DEBUG
+ qDebug() << "Parse error, trying to recover.";
+#endif
QString msg;
int token = token_buffer[0].token;
if (token < 0 || token >= TERMINAL_COUNT)
@@ -4419,18 +4424,13 @@ ExportSpecifier: IdentifierName T_AS IdentifierName;
for (int *tk = tokens; *tk != EOF_SYMBOL; ++tk) {
int a = t_action(errorState, *tk);
if (a > 0 && t_action(a, yytoken)) {
+#ifdef PARSER_DEBUG
+ qDebug() << "Parse error, trying to recover (2).";
+#endif
const QString msg = QCoreApplication::translate("QQmlParser", "Expected token `%1'").arg(QLatin1String(spell[*tk]));
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
- yytoken = *tk;
- yylval = 0;
- yylloc = token_buffer[0].loc;
- yylloc.length = 0;
-
- first_token = &token_buffer[0];
- last_token = &token_buffer[2];
-
- action = errorState;
+ pushToken(*tk);
goto _Lcheck_token;
}
}
@@ -4445,12 +4445,7 @@ ExportSpecifier: IdentifierName T_AS IdentifierName;
const QString msg = QCoreApplication::translate("QQmlParser", "Expected token `%1'").arg(QLatin1String(spell[tk]));
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
- yytoken = tk;
- yylval = 0;
- yylloc = token_buffer[0].loc;
- yylloc.length = 0;
-
- action = errorState;
+ pushToken(tk);
goto _Lcheck_token;
}
}
diff --git a/tests/auto/qml/v4misc/tst_v4misc.cpp b/tests/auto/qml/v4misc/tst_v4misc.cpp
index f8e76fdf5c..da7b610978 100644
--- a/tests/auto/qml/v4misc/tst_v4misc.cpp
+++ b/tests/auto/qml/v4misc/tst_v4misc.cpp
@@ -114,6 +114,7 @@ void tst_v4misc::parserMisc_data()
QTest::newRow("for (var f in ++!binaryMathg) ;") << QString("ReferenceError: Prefix ++ operator applied to value that is not a reference.");
QTest::newRow("for (va() in obj) {}") << QString("ReferenceError: Invalid left-hand side expression for 'in' expression");
QTest::newRow("[1]=7[A=8=9]") << QString("ReferenceError: left-hand side of assignment operator is not an lvalue");
+ QTest::newRow("var asmvalsLen = asmvals{{{{{ngth}}}}};") << QString("SyntaxError: Expected token `;'");
}
void tst_v4misc::parserMisc()