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)
{
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;
}