diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-02-09 14:57:21 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-02-13 14:48:30 +0000 |
commit | fdabe1c8ac9c43648718b66bfb4194439a3e6abb (patch) | |
tree | 21c96f68fa30398a63b919349b82e0ead84c5258 /src/qml | |
parent | f145f33d529c2b59ace7a3cdfd5463e68787f40b (diff) |
Fix a potential crash in pushWithScope
toObject() can potentially allocate a new object. If a GC accurs between
that allocation and newWithContext(), we'd free the withObject
Fixes a crash on test262 ch12/12.10/12.10-2-1 when running it with
aggressive GC.
Change-Id: Id8e957a748658a8f31ae39ff83509e9574ed51f7
Reviewed-by: Robin Burchell <robin.burchell@crimson.no>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 7f184f8221..6590054bf3 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1264,12 +1264,16 @@ ReturnedValue Runtime::method_unwindException(ExecutionEngine *engine) */ void Runtime::method_pushWithScope(const Value &o, NoThrowEngine *engine) { - engine->pushContext(engine->currentContext->newWithContext(o.toObject(engine))); + QV4::Value *v = engine->jsAlloca(1); + Heap::Object *withObject = o.toObject(engine); + *v = withObject; + engine->pushContext(engine->currentContext->newWithContext(withObject)); Q_ASSERT(engine->jsStackTop == engine->currentContext + 2); } void Runtime::method_pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex) { + engine->jsAlloca(1); // keep this symmetric with pushWithScope ExecutionContext *c = engine->currentContext; engine->pushContext(c->newCatchContext(c->d()->compilationUnit->runtimeStrings[exceptionVarNameIndex], engine->catchException(0))); Q_ASSERT(engine->jsStackTop == engine->currentContext + 2); @@ -1279,7 +1283,7 @@ void Runtime::method_popScope(NoThrowEngine *engine) { Q_ASSERT(engine->jsStackTop == engine->currentContext + 2); engine->popContext(); - engine->jsStackTop -= 2; + engine->jsStackTop -= 3; } void Runtime::method_declareVar(ExecutionEngine *engine, bool deletable, int nameIndex) |