diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 63ee5f3158..ebb3665e0c 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -994,8 +994,12 @@ void QCborContainerPrivate::replaceAt_complex(Element &e, const QCborValue &valu e = value.container->elements.at(value.n); // Copy string data, if any - if (const ByteData *b = value.container->byteData(value.n)) - e.value = addByteData(b->byte(), b->len); + if (const ByteData *b = value.container->byteData(value.n)) { + if (this == value.container) + e.value = addByteData(b->toByteArray(), b->len); + else + e.value = addByteData(b->byte(), b->len); + } if (disp == MoveContainer) value.container->deref(); @@ -2649,7 +2653,7 @@ void QCborValueRef::assign(QCborValueRef that, QCborValue &&other) void QCborValueRef::assign(QCborValueRef that, const QCborValueRef other) { // ### optimize? - assign(that, other.concrete()); + that = other.concrete(); } QCborValue QCborValueRef::concrete(QCborValueRef self) noexcept diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 6d8161c1f9..c70518fbee 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -79,6 +79,7 @@ private slots: void mapEmptyDetach(); void mapSimpleInitializerList(); void mapMutation(); + void mapMutateWithCopies(); void mapStringValues(); void mapStringKeys(); void mapInsertRemove_data() { basics_data(); } @@ -923,6 +924,76 @@ void tst_QCborValue::mapMutation() QCOMPARE(val[any][3].toMap().size(), 1); } +void tst_QCborValue::mapMutateWithCopies() +{ + { + QCborMap map; + map[QLatin1String("prop1")] = "TEST"; + QCOMPARE(map.size(), 1); + QCOMPARE(map.value("prop1"), "TEST"); + + map[QLatin1String("prop2")] = map.value("prop1"); + QCOMPARE(map.size(), 2); + QCOMPARE(map.value("prop1"), "TEST"); + QCOMPARE(map.value("prop2"), "TEST"); + } + { + // see QTBUG-83366 + QCborMap map; + map[QLatin1String("value")] = "TEST"; + QCOMPARE(map.size(), 1); + QCOMPARE(map.value("value"), "TEST"); + + QCborValue v = map.value("value"); + map[QLatin1String("prop2")] = v; + QCOMPARE(map.size(), 2); + QCOMPARE(map.value("value"), "TEST"); + QCOMPARE(map.value("prop2"), "TEST"); + } + { + QCborMap map; + map[QLatin1String("value")] = "TEST"; + QCOMPARE(map.size(), 1); + QCOMPARE(map.value("value"), "TEST"); + + // same as previous, but this is a QJsonValueRef + QCborValueRef rv = map[QLatin1String("prop2")]; + rv = map[QLatin1String("value")]; + QCOMPARE(map.size(), 2); + QCOMPARE(map.value("value"), "TEST"); + QCOMPARE(map.value("prop2"), "TEST"); + } + { + QCborMap map; + map[QLatin1String("value")] = "TEST"; + QCOMPARE(map.size(), 1); + QCOMPARE(map.value("value"), "TEST"); + + // same as previous, but now we call the operator[] that reallocates + // after we create the source QCborValueRef + QCborValueRef rv = map[QLatin1String("value")]; + map[QLatin1String("prop2")] = rv; + QCOMPARE(map.size(), 2); + QCOMPARE(map.value("value"), "TEST"); + QCOMPARE(map.value("prop2"), "TEST"); + } + { + QCborMap map; + map[QLatin1String("value")] = "TEST"; + QCOMPARE(map.size(), 1); + QCOMPARE(map.value("value"), "TEST"); + + QCborValueRef v = map[QLatin1String("value")]; + QCborMap map2 = map; + map.insert(QLatin1String("prop2"), v); + QCOMPARE(map.size(), 2); + QCOMPARE(map.value("value"), "TEST"); + QCOMPARE(map.value("prop2"), "TEST"); + QCOMPARE(map2.size(), 1); + QCOMPARE(map2.value("value"), "TEST"); + } +} + void tst_QCborValue::arrayPrepend() { QCborArray a;