Blob Blame History Raw
From 6d54a59bd725ba83e758236c5ff0fc7855109dac Mon Sep 17 00:00:00 2001
From: Simon Hausmann <simon.hausmann@qt.io>
Date: Thu, 2 Jun 2016 15:57:41 +0200
Subject: [PATCH 27/40] Fix crash when using with statement with an expression
 that throws

We need to evaluate the expression for the "with" statement that is supposed to
define the new scope _before_ opening up the scope, otherwise - when the
evaluation of the expression throws an exception - we'll try to pop the "with"
scope we couldn't open in the first place.

[ChangeLog][QtQml] Fix crash when using the "with" statement with an expression
that throws an exception.

Task-number: QTBUG-53794
Change-Id: I7733f5a4c5d844916302b9a91c789a0f6b421e8a
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
---
 src/qml/compiler/qv4codegen.cpp            | 5 +++--
 tests/auto/qml/qjsengine/tst_qjsengine.cpp | 9 +++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index ea82d07..c14163a 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2718,6 +2718,9 @@ bool Codegen::visit(WithStatement *ast)
 
     _function->hasWith = true;
 
+    const int withObject = _block->newTemp();
+    _block->MOVE(_block->TEMP(withObject), *expression(ast->expression));
+
     // need an exception handler for with to cleanup the with scope
     IR::BasicBlock *withExceptionHandler = _function->newBasicBlock(exceptionHandler());
     withExceptionHandler->EXP(withExceptionHandler->CALL(withExceptionHandler->NAME(IR::Name::builtin_pop_scope, 0, 0), 0));
@@ -2732,8 +2735,6 @@ bool Codegen::visit(WithStatement *ast)
 
     _block->JUMP(withBlock);
     _block = withBlock;
-    int withObject = _block->newTemp();
-    _block->MOVE(_block->TEMP(withObject), *expression(ast->expression));
     IR::ExprList *args = _function->New<IR::ExprList>();
     args->init(_block->TEMP(withObject));
     _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_push_with_scope, 0, 0), args));
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 9a0865c..8594aec 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -193,6 +193,8 @@ private slots:
 
     void v4FunctionWithoutQML();
 
+    void withNoContext();
+
 signals:
     void testSignal();
 };
@@ -3840,6 +3842,13 @@ void tst_QJSEngine::v4FunctionWithoutQML()
     QVERIFY(obj.called);
 }
 
+void tst_QJSEngine::withNoContext()
+{
+    // Don't crash (QTBUG-53794)
+    QJSEngine engine;
+    engine.evaluate("with (noContext) true");
+}
+
 QTEST_MAIN(tst_QJSEngine)
 
 #include "tst_qjsengine.moc"
-- 
1.9.3