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>
This commit is contained in:
Marc Mutz 2016-05-20 06:28:26 +02:00
parent a1de7c40f4
commit bbb440bab2

View File

@ -269,25 +269,11 @@ QJsonValue::QJsonValue(const QJsonValue &other)
*/ */
QJsonValue &QJsonValue::operator =(const QJsonValue &other) QJsonValue &QJsonValue::operator =(const QJsonValue &other)
{ {
if (t == String && stringData && !stringData->ref.deref()) QJsonValue copy(other);
free(stringData); // swap(copy);
qSwap(dbl, copy.dbl);
t = other.t; qSwap(d, copy.d);
dbl = other.dbl; qSwap(t, copy.t);
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();
return *this; return *this;
} }