summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2020-07-21 11:34:44 +0200
committerLars Knoll <lars.knoll@qt.io>2020-08-04 11:28:33 +0000
commit652062dde33ddb0ecaf4bb9f38055d8ab87c462b (patch)
tree17a3ebf808541096fa67e537214304e74d91c21b /tests
parent2b0db5593916680f3eee34c4b4dd2de16c5736a2 (diff)
QNotifiedProperty: avoid crash
We can end up in a situation where a (soon to be destroyed) observer is owned by a binding which is about to be deleted. If in that situation the binding is destroyed first, we end up with a dangling pointer and ensuing memory corruption. Instead, we now first transfer the ownership of the observer and only destroy the binding afterwards. Fixes: QTBUG-85824 Change-Id: I721c0319281ada981ae7896bd2e02e9a0cc901b8 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp
index 41cf60b55f..74a81cc93b 100644
--- a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp
+++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp
@@ -73,6 +73,7 @@ private slots:
void notifiedPropertyWithOldValueCallback();
void notifiedPropertyWithGuard();
void typeNoOperatorEqual();
+ void bindingValueReplacement();
};
void tst_QProperty::functorBinding()
@@ -1058,6 +1059,34 @@ void tst_QProperty::typeNoOperatorEqual()
QVERIFY(u1.changedCalled);
}
+
+struct Test {
+ void notify() {};
+ bool bindText(int);
+ bool bindIconText(int);
+ QProperty<int> text;
+ QNotifiedProperty<int, &Test::notify, &Test::bindIconText> iconText;
+};
+
+bool Test::bindIconText(int) {
+ Q_UNUSED(iconText.value()); // force read
+ if (!iconText.hasBinding()) {
+ iconText.setBinding(this, [=]() { return 0; });
+ }
+ return true;
+}
+
+void tst_QProperty::bindingValueReplacement()
+{
+ Test test;
+ test.text = 0;
+ test.bindIconText(0);
+ test.iconText.setValue(&test, 42); // should not crash
+ QCOMPARE(test.iconText.value(), 42);
+ test.text = 1;
+ QCOMPARE(test.iconText.value(), 42);
+}
+
QTEST_MAIN(tst_QProperty);
#include "tst_qproperty.moc"