From ddc7b3c1565b5f7100df4d13e5501f76db2730ee Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 8 Apr 2020 11:40:42 -0300 Subject: QJsonObject: add missing detach2() calls The refactoring to use CBOR missed two places where we could assign from the same object and thus cause corruption. In fixing this issue, I found a design flaw in QJsonObject, see Q_EXPECT_FAILing unit test and task QTBUG-83398. [ChangeLog][QtCore][QJsonObject] Fixed a regression from 5.13 that incorrect results when assigning elements from an object to itself. Fixes: QTBUG-83366 Change-Id: Ibdc95e9af7bd456a94ecfffd1603df24b06713aa Reviewed-by: Ulf Hermann --- src/corelib/serialization/qjsonobject.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/corelib/serialization') diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index b76e50e2d2..850e878571 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -452,9 +452,11 @@ QJsonValueRef QJsonObject::atImpl(T key) bool keyExists = false; int index = indexOf(o, key, &keyExists); if (!keyExists) { + detach2(o->elements.length() / 2 + 1); o->insertAt(index, key); o->insertAt(index + 1, QCborValue::fromJsonValue(QJsonValue())); } + // detaching will happen if and when this QJsonValueRef is assigned to return QJsonValueRef(this, index / 2); } @@ -1469,6 +1471,7 @@ QJsonValue QJsonObject::valueAt(int i) const void QJsonObject::setValueAt(int i, const QJsonValue &val) { Q_ASSERT(o && i >= 0 && 2 * i + 1 < o->elements.length()); + detach2(); if (val.isUndefined()) { o->removeAt(2 * i + 1); o->removeAt(2 * i); -- cgit v1.2.3 From 57a57fda78bab652e3fb79677bd828b0f0b49962 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 8 Apr 2020 11:47:33 -0300 Subject: QCborMap: fix assigning elements from the map to itself Similar to the QJsonObject issue of the previous commit (found with the same tests, but not the same root cause). One fix was that copying of byte data from the QByteArray to itself won't work if the array reallocates. The second was that assign(*that, other.concrete()); fails to set other.d to null after moving. By calling the operator=, we get the proper sequence of events. [ChangeLog][QtCore][QCborMap] Fixed some issues relating to assigning elements from a map to itself. Note: QCborMap is not affected by the design flaw discovered in QJsonObject because it always appends elements (it's unsorted), so existing QCborValueRef references still refer to the same value. Task-number: QTBUG-83366 Change-Id: Ibdc95e9af7bd456a94ecfffd1603df846f46094d Reviewed-by: Ulf Hermann --- src/corelib/serialization/qcborvalue.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/corelib/serialization') 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 -- cgit v1.2.3 From 954d66e5720b5dd7d31de62364f5e2a8df0bcac3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 8 Apr 2020 11:42:06 -0300 Subject: QCborArray: fix operator[] that extends the array This was never tested. The infinite loop in QCborContainerPrivate::grow is the proof. [ChangeLog][QtCore][QCborArray] Fixed an infinite loop when operator[] was called with with an index larger than the array's size plus 1. Change-Id: Ibdc95e9af7bd456a94ecfffd1603df3855c73f20 Reviewed-by: Ulf Hermann --- src/corelib/serialization/qcborvalue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib/serialization') diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index ebb3665e0c..c45a09ad99 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -956,7 +956,7 @@ QCborContainerPrivate *QCborContainerPrivate::grow(QCborContainerPrivate *d, qsi d = detach(d, index + 1); Q_ASSERT(d); int j = d->elements.size(); - while (j < index) + while (j++ < index) d->append(Undefined()); return d; } -- cgit v1.2.3 From 712ed3d5d6645ef4a091e22f508de1ada8fdf94c Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 8 Apr 2020 13:25:13 +0200 Subject: Switch to using versioned deprecated macros Change-Id: I4728e6ecc7218a6c98fd3a10e50e6edd1704fb83 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/corelib/serialization/qtextstream.h | 48 ++++++++++++++++----------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'src/corelib/serialization') diff --git a/src/corelib/serialization/qtextstream.h b/src/corelib/serialization/qtextstream.h index 0d8a9a548e..97d596137e 100644 --- a/src/corelib/serialization/qtextstream.h +++ b/src/corelib/serialization/qtextstream.h @@ -271,30 +271,30 @@ Q_CORE_EXPORT QTextStream &ws(QTextStream &s); #if QT_DEPRECATED_SINCE(5, 15) // This namespace only exists for 'using namespace' declarations. namespace QTextStreamFunctions { -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::bin") QTextStream &bin(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::oct") QTextStream &oct(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::dec") QTextStream &dec(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::hex") QTextStream &hex(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::showbase") QTextStream &showbase(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::forcesign") QTextStream &forcesign(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::forcepoint") QTextStream &forcepoint(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::noshowbase") QTextStream &noshowbase(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::noforcesign") QTextStream &noforcesign(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::noforcepoint") QTextStream &noforcepoint(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::uppercasebase") QTextStream &uppercasebase(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::uppercasedigits") QTextStream &uppercasedigits(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::lowercasebase") QTextStream &lowercasebase(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::lowercasedigits") QTextStream &lowercasedigits(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::fixed") QTextStream &fixed(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::scientific") QTextStream &scientific(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::left") QTextStream &left(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::right") QTextStream &right(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::center") QTextStream ¢er(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::endl") QTextStream &endl(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::flush") QTextStream &flush(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::reset") QTextStream &reset(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::bom") QTextStream &bom(QTextStream &s); -Q_CORE_EXPORT QT_DEPRECATED_X("Use Qt::ws") QTextStream &ws(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::bin") QTextStream &bin(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::oct") QTextStream &oct(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::dec") QTextStream &dec(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::hex") QTextStream &hex(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::showbase") QTextStream &showbase(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::forcesign") QTextStream &forcesign(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::forcepoint") QTextStream &forcepoint(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::noshowbase") QTextStream &noshowbase(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::noforcesign") QTextStream &noforcesign(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::noforcepoint") QTextStream &noforcepoint(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::uppercasebase") QTextStream &uppercasebase(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::uppercasedigits") QTextStream &uppercasedigits(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::lowercasebase") QTextStream &lowercasebase(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::lowercasedigits") QTextStream &lowercasedigits(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::fixed") QTextStream &fixed(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::scientific") QTextStream &scientific(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::left") QTextStream &left(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::right") QTextStream &right(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::center") QTextStream ¢er(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::endl") QTextStream &endl(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::flush") QTextStream &flush(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::reset") QTextStream &reset(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::bom") QTextStream &bom(QTextStream &s); +Q_CORE_EXPORT QT_DEPRECATED_VERSION_X(5, 15, "Use Qt::ws") QTextStream &ws(QTextStream &s); } // namespace QTextStreamFunctions QT_WARNING_PUSH -- cgit v1.2.3