diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-01-02 21:48:12 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-01-06 09:23:00 +0000 |
commit | 18e9d3df8a6ef3a5022472e57727c79ee26beeaa (patch) | |
tree | b7975d2bb398e05fc9260dbf59d9fb2df9bfe4e4 /src | |
parent | b9565b3aff7750968e8e885832c2ebd2997969ce (diff) |
QQmlObjectCreator: Do not crash on read-only bindable
If the binding was not actually set (because the bindable is readonly)
then it's dead after the pop_front. We cannot examine it anymore, and we
don't have to.
Fixes: QTBUG-109597
Change-Id: I3bf0ca501aa9ad45a64ad181b685ca6d9d325231
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 4dfcaa7ee8273914ea8cd9fd232064ce95cb15d1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index e85260f670..c18ff8742a 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1475,16 +1475,24 @@ bool QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt) void *argv[] = { &bindable }; // allow interception target->metaObject()->metacall(target, QMetaObject::BindableProperty, index, argv); - bindable.setBinding(qmlBinding); + const bool success = bindable.setBinding(qmlBinding); + + // Only pop_front after setting the binding as the bindings are refcounted. sharedState->allQPropertyBindings.pop_front(); - if (auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) { - auto qmlBindingPriv = static_cast<QQmlPropertyBinding *>(priv); - auto jsExpression = qmlBindingPriv->jsExpression(); - const bool canRemove = !qmlBinding.error().hasError() && !qmlBindingPriv->hasDependencies() - && !jsExpression->hasUnresolvedNames(); - if (canRemove) - bindable.takeBinding(); + + // If the binding was actually not set, it's deleted now. + if (success) { + if (auto priv = QPropertyBindingPrivate::get(qmlBinding); priv->hasCustomVTable()) { + auto qmlBindingPriv = static_cast<QQmlPropertyBinding *>(priv); + auto jsExpression = qmlBindingPriv->jsExpression(); + const bool canRemove = !qmlBinding.error().hasError() + && !qmlBindingPriv->hasDependencies() + && !jsExpression->hasUnresolvedNames(); + if (canRemove) + bindable.takeBinding(); + } } + if (watcher.hasRecursed() || interrupt.shouldInterrupt()) return false; } |