summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2016-05-20 06:28:26 +0200
committerMarc Mutz <marc.mutz@kdab.com>2016-06-01 20:59:16 +0000
commitbbb440bab261fecc7c9baf779dadf36659d3cf6f (patch)
treed68c758d32e8ab6b331f447fae9173bb7a8d031b /src/corelib
parenta1de7c40f4a22f996fcf922e69315c1f2cea6e96 (diff)
QJsonValue: fix use-after-free in assignment operator
The assignment operator of a String QJsonValue that holds the only remaining reference to the QString::Data block was freeing the block before obtaining its own reference, leading to a use-after-free in the case where *this was passed as 'other' (self-assignment). Fixed by reformulating the assignment operator in terms of the copy ctor, using the copy-swap idiom, with the twist that QJsonValue doesn't, yet, have a swap member function, so we use three per-member qSwap()s. Change-Id: I3c5ccc4d9f32c7593af3fc6a0edbf12b7feb1391 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/json/qjsonvalue.cpp24
1 files changed, 5 insertions, 19 deletions
diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp
index 76e5ae562f..c9f3ec35fe 100644
--- a/src/corelib/json/qjsonvalue.cpp
+++ b/src/corelib/json/qjsonvalue.cpp
@@ -269,25 +269,11 @@ QJsonValue::QJsonValue(const QJsonValue &other)
*/
QJsonValue &QJsonValue::operator =(const QJsonValue &other)
{
- if (t == String && stringData && !stringData->ref.deref())
- free(stringData);
-
- t = other.t;
- dbl = other.dbl;
-
- if (d != other.d) {
-
- if (d && !d->ref.deref())
- delete d;
- d = other.d;
- if (d)
- d->ref.ref();
-
- }
-
- if (t == String && stringData)
- stringData->ref.ref();
-
+ QJsonValue copy(other);
+ // swap(copy);
+ qSwap(dbl, copy.dbl);
+ qSwap(d, copy.d);
+ qSwap(t, copy.t);
return *this;
}