diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2025-09-10 15:00:39 +0200 |
|---|---|---|
| committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2025-09-12 03:27:53 +0000 |
| commit | 1f89af3cfdb44a4b892a4968adc08ce23f694620 (patch) | |
| tree | 37d05e6cb24797711926616f5c0c2be5a7835790 | |
| parent | 407ee44ae1f871c74b06adc6c2457d618d6e8c7e (diff) | |
QtQml: Check for locals in metatypes stack frame before accessing them
ScopedStackFrame has no locals and we don't want to crash if we manage
to run the GC while e.g. initializing a component.
Amends commmit 2d016a2653c59f10a57dc1903b817f71d16d0622
Fixes: QTBUG-140057
Pick-to: 6.8
Change-Id: I7aeb39d6cb1f0ca0a661b8cfa2e7c159f968e224
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
(cherry picked from commit 024e43c68f77f6462c9ffd9e01a2b29feeefa5a3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit c4bf8c9f801cc78ab2b493f43a89cf86f2ea5b96)
| -rw-r--r-- | src/qml/memory/qv4mm.cpp | 14 | ||||
| -rw-r--r-- | tests/auto/qml/qv4mm/tst_qv4mm.cpp | 13 |
2 files changed, 20 insertions, 7 deletions
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index bae688a13c..ab7f7599c3 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -1480,13 +1480,13 @@ void MemoryManager::collectFromJSStack(MarkStack *markStack) const if (!frame->isMetaTypesFrame()) continue; - const QQmlPrivate::AOTTrackedLocalsStorage *locals - = static_cast<const MetaTypesStackFrame *>(frame)->locals(); - - // locals have to be initialized first thing when calling the function - Q_ASSERT(locals); - - locals->markObjects(markStack); + if (const QQmlPrivate::AOTTrackedLocalsStorage *locals + = static_cast<const MetaTypesStackFrame *>(frame)->locals()) { + // Actual AOT-compiled functions initialize the locals firsth thing when they + // are called. However, the ScopedStackFrame has no locals, but still uses a + // MetaTypesStackFrame. + locals->markObjects(markStack); + } } } diff --git a/tests/auto/qml/qv4mm/tst_qv4mm.cpp b/tests/auto/qml/qv4mm/tst_qv4mm.cpp index 561ad2b6cc..d8b342bd52 100644 --- a/tests/auto/qml/qv4mm/tst_qv4mm.cpp +++ b/tests/auto/qml/qv4mm/tst_qv4mm.cpp @@ -57,6 +57,8 @@ private slots: void scopedConvertToObjectFromReturnedValueDoesNotAccessGarbageOnTheStackOnAllocation(); void scopedConvertToStringFromValueDoesNotAccessGarbageOnTheStackOnAllocation(); void scopedConvertToObjectFromValueDoesNotAccessGarbageOnTheStackOnAllocation(); + + void dontCrashOnScopedStackFrame(); }; tst_qv4mm::tst_qv4mm() @@ -1019,6 +1021,17 @@ void tst_qv4mm::scopedConvertToObjectFromValueDoesNotAccessGarbageOnTheStackOnAl QV4::ScopedObject object(scope, QV4::StaticValue::fromBoolean(true).asValue<QV4::Value>(), QV4::ScopedObject::Convert); } +void tst_qv4mm::dontCrashOnScopedStackFrame() +{ + QJSEngine jsengine; + QV4::ExecutionEngine *engine = jsengine.handle(); + + QV4::Scope scope(engine); + QV4::ScopedStackFrame frame(scope, engine->rootContext()); + + jsengine.collectGarbage(); +} + QTEST_MAIN(tst_qv4mm) #include "tst_qv4mm.moc" |
