aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-11-10 09:36:13 +0100
committerUlf Hermann <ulf.hermann@qt.io>2021-11-11 10:50:44 +0100
commita43fd647ed292410dc13f5bc53c6958b0f653fbd (patch)
treeba1b5bfb3dddeb254bec0264f3896ad6ed65f821
parentf9147af0bdef7769498dbbc987c7a49b64de9ee9 (diff)
Do not crash on self-assignment of QQmlProperty
If you had a QQmlPropertyPrivate with only one reference, assigning its QQmlProperty to itself would delete the QQmlPropertyPrivate. Change-Id: I73f8e6df63af09d3f43a101749a5800153499057 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit d1409760ec2b4c85b3c29439e8ce8ec3ec68d5a4)
-rw-r--r--src/qml/qml/qqmlproperty.cpp8
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp15
2 files changed, 15 insertions, 8 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 54e17cdf12..1cfd2d83d3 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -598,12 +598,8 @@ QObject *QQmlProperty::object() const
*/
QQmlProperty &QQmlProperty::operator=(const QQmlProperty &other)
{
- if (d)
- d->release();
- d = other.d;
- if (d)
- d->addref();
-
+ QQmlProperty copied(other);
+ qSwap(d, copied.d);
return *this;
}
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 5363cc8fcb..4032a4448d 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -1943,7 +1943,8 @@ void tst_qqmlproperty::copy()
{
PropertyObject object;
- QQmlProperty *property = new QQmlProperty(&object, QLatin1String("defaultProperty"));
+ QScopedPointer<QQmlProperty> property(
+ new QQmlProperty(&object, QLatin1String("defaultProperty")));
QCOMPARE(property->name(), QString("defaultProperty"));
QCOMPARE(property->read(), QVariant(10));
QCOMPARE(property->type(), QQmlProperty::Property);
@@ -1966,7 +1967,7 @@ void tst_qqmlproperty::copy()
QCOMPARE(p2.propertyTypeCategory(), QQmlProperty::Normal);
QCOMPARE(p2.propertyType(), (int)QVariant::Int);
- delete property; property = nullptr;
+ property.reset();
QCOMPARE(p1.name(), QString("defaultProperty"));
QCOMPARE(p1.read(), QVariant(10));
@@ -1979,6 +1980,16 @@ void tst_qqmlproperty::copy()
QCOMPARE(p2.type(), QQmlProperty::Property);
QCOMPARE(p2.propertyTypeCategory(), QQmlProperty::Normal);
QCOMPARE(p2.propertyType(), (int)QVariant::Int);
+
+ p1 = QQmlProperty();
+ QQmlPropertyPrivate *p2d = QQmlPropertyPrivate::get(p2);
+ QCOMPARE(p2d->count(), 1);
+
+ // Use a pointer to avoid compiler warning about self-assignment.
+ QQmlProperty *p2p = &p2;
+ *p2p = p2;
+
+ QCOMPARE(p2d->count(), 1);
}
void tst_qqmlproperty::noContext()