diff options
author | Lars Knoll <lars.knoll@qt.io> | 2019-11-16 23:25:26 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-07-06 21:29:58 +0200 |
commit | 76004502baa118016c8e0f32895af7a822f1ba37 (patch) | |
tree | 3fb524e333cb2edf6e983c4898c76f9eebb04eb4 /tests | |
parent | 2e51686746c45055e5bb74f58e0c159bfb6a8c13 (diff) |
Get rid of shared null for QByteArray, QString and QVector
As a side effect, data() can now return a nullptr. This
has the potential to cause crashes in existig code. To work
around this, return an empty string from QString::data()
and QByteArray::data() for now.
For Qt 6 (and once all our internal issues are fixed), data()
will by default return a nullptr for a null QString, but we'll
offer a #define to enable backwards compatible behavior.
Change-Id: I4f66d97ff1dce3eb99a239f1eab9106fa9b1741a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp | 2 | ||||
-rw-r--r-- | tests/auto/corelib/text/qstring/tst_qstring.cpp | 6 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qarraydata/simplevector.h | 7 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp | 46 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qlist/tst_qlist.cpp | 50 | ||||
-rw-r--r-- | tests/auto/tools/qmakelib/tst_qmakelib.cpp | 2 |
6 files changed, 75 insertions, 38 deletions
diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp index 73d9f8e765..940865b98e 100644 --- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp @@ -2277,7 +2277,7 @@ void tst_QByteArray::literals() QVERIFY(str.length() == 4); QCOMPARE(str.capacity(), 0); QVERIFY(str == "abcd"); - QVERIFY(str.data_ptr()->isStatic()); + QVERIFY(!str.data_ptr()->isMutable()); const char *s = str.constData(); QByteArray str2 = str; diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index 81a08eb59e..4d2e91a694 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -4014,7 +4014,7 @@ void tst_QString::fromRawData() { const QChar ptr[] = { 0x1234, 0x0000 }; QString cstr = QString::fromRawData(ptr, 1); - QVERIFY(cstr.isDetached()); + QVERIFY(!cstr.isDetached()); QVERIFY(cstr.constData() == ptr); QVERIFY(cstr == QString(ptr, 1)); cstr.squeeze(); @@ -4036,7 +4036,7 @@ void tst_QString::setRawData() // This just tests the fromRawData() fallback QVERIFY(!cstr.isDetached()); cstr.setRawData(ptr, 1); - QVERIFY(cstr.isDetached()); + QVERIFY(!cstr.isDetached()); QVERIFY(cstr.constData() == ptr); QVERIFY(cstr == QString(ptr, 1)); @@ -6571,7 +6571,7 @@ void tst_QString::literals() QVERIFY(str.length() == 4); QCOMPARE(str.capacity(), 0); QVERIFY(str == QLatin1String("abcd")); - QVERIFY(str.data_ptr()->isStatic()); + QVERIFY(!str.data_ptr()->isMutable()); const QChar *s = str.constData(); QString str2 = str; diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h index 94cee5d887..1a9ed35b7a 100644 --- a/tests/auto/corelib/tools/qarraydata/simplevector.h +++ b/tests/auto/corelib/tools/qarraydata/simplevector.h @@ -153,7 +153,7 @@ public: if (d->flags() & Data::CapacityReserved) return; if (!d->isShared()) { - d->flags() |= Data::CapacityReserved; + d.setFlag(Data::CapacityReserved); return; } } @@ -338,10 +338,9 @@ public: d.detach(); } - static SimpleVector fromRawData(const T *data, size_t size, - QArrayData::ArrayOptions options = Data::DefaultRawFlags) + static SimpleVector fromRawData(const T *data, size_t size) { - return SimpleVector(Data::fromRawData(data, size, options)); + return SimpleVector(Data::fromRawData(data, size)); } private: diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index 7b42b27f6e..128bc51553 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -156,20 +156,15 @@ void tst_QArrayData::sharedNullEmpty() void tst_QArrayData::simpleVector() { - QArrayData data0 = { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0 }; - QStaticArrayData<int, 7> data1 = { - { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0 }, - { 0, 1, 2, 3, 4, 5, 6 } - }; - + int data[] = { 0, 1, 2, 3, 4, 5, 6 }; int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; SimpleVector<int> v1; SimpleVector<int> v2(v1); - SimpleVector<int> v3(static_cast<QTypedArrayData<int> *>(&data0), 0, 0); - SimpleVector<int> v4(data1); - SimpleVector<int> v5(static_cast<QTypedArrayData<int> *>(&data0), 0, 0); - SimpleVector<int> v6(data1); + SimpleVector<int> v3(nullptr, nullptr, 0); + SimpleVector<int> v4(nullptr, data, 0); + SimpleVector<int> v5(nullptr, data, 1); + SimpleVector<int> v6(nullptr, data, 7); SimpleVector<int> v7(10, 5); SimpleVector<int> v8(array, array + sizeof(array)/sizeof(*array)); @@ -190,7 +185,7 @@ void tst_QArrayData::simpleVector() QVERIFY(v2.isEmpty()); QVERIFY(v3.isEmpty()); QVERIFY(v4.isEmpty()); - QVERIFY(v5.isEmpty()); + QVERIFY(!v5.isEmpty()); QVERIFY(!v6.isEmpty()); QVERIFY(!v7.isEmpty()); QVERIFY(!v8.isEmpty()); @@ -199,7 +194,7 @@ void tst_QArrayData::simpleVector() QCOMPARE(v2.size(), size_t(0)); QCOMPARE(v3.size(), size_t(0)); QCOMPARE(v4.size(), size_t(0)); - QCOMPARE(v5.size(), size_t(0)); + QCOMPARE(v5.size(), size_t(1)); QCOMPARE(v6.size(), size_t(7)); QCOMPARE(v7.size(), size_t(10)); QCOMPARE(v8.size(), size_t(10)); @@ -248,13 +243,13 @@ void tst_QArrayData::simpleVector() QVERIFY(v1 == v2); QVERIFY(v1 == v3); QVERIFY(v1 == v4); - QVERIFY(v1 == v5); + QVERIFY(v1 != v5); QVERIFY(!(v1 == v6)); QVERIFY(v1 != v6); QVERIFY(v4 != v6); QVERIFY(v5 != v6); - QVERIFY(!(v1 != v5)); + QVERIFY(!(v1 == v5)); QVERIFY(v1 < v6); QVERIFY(!(v6 < v1)); @@ -428,17 +423,10 @@ void tst_QArrayData::simpleVectorReserve_data() QTest::newRow("empty") << SimpleVector<int>(0, 42) << size_t(0) << size_t(0); QTest::newRow("non-empty") << SimpleVector<int>(5, 42) << size_t(5) << size_t(5); - static const QStaticArrayData<int, 15> array = { - { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0 }, - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } }; - const QArrayDataPointerRef<int> p = { - static_cast<QTypedArrayData<int> *>( - const_cast<QArrayData *>(&array.header)), - const_cast<int *>(array.data), - sizeof(array.data) / sizeof(array.data[0]) }; - - QTest::newRow("static") << SimpleVector<int>(p) << size_t(0) << size_t(15); - QTest::newRow("raw-data") << SimpleVector<int>::fromRawData(array.data, 15) << size_t(0) << size_t(15); + static const int array[] = + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + + QTest::newRow("raw-data") << SimpleVector<int>::fromRawData(array, 15) << size_t(0) << size_t(15); } void tst_QArrayData::simpleVectorReserve() @@ -519,7 +507,7 @@ void tst_QArrayData::allocate_data() }; QArrayData *shared_empty; - QArrayData::allocate(&shared_empty, 1, alignof(QArrayData), 0); + (void)QArrayData::allocate(&shared_empty, 1, alignof(QArrayData), 0); QVERIFY(shared_empty); struct { @@ -1180,15 +1168,15 @@ void fromRawData_impl() { // Default: Immutable, sharable SimpleVector<T> raw = SimpleVector<T>::fromRawData(array, - sizeof(array)/sizeof(array[0]), QArrayData::DefaultRawFlags); + sizeof(array)/sizeof(array[0])); QCOMPARE(raw.size(), size_t(11)); QCOMPARE((const T *)raw.constBegin(), array); QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0]))); - QVERIFY(!raw.isShared()); + QVERIFY(raw.isShared()); QVERIFY(SimpleVector<T>(raw).isSharedWith(raw)); - QVERIFY(!raw.isShared()); + QVERIFY(raw.isShared()); // Detach QCOMPARE(raw.back(), T(11)); diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index df3f2023d6..ddf5e9c30a 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -336,6 +336,8 @@ private slots: void emplaceWithElementFromTheSameContainer(); void emplaceWithElementFromTheSameContainer_data(); + void fromReadOnlyData() const; + private: template<typename T> void copyConstructor() const; template<typename T> void add() const; @@ -2830,5 +2832,53 @@ void tst_QList::emplaceConsistentWithStdVectorImpl() const vecEq(qVec, stdVec); } +void tst_QList::fromReadOnlyData() const +{ + { + QVector<char> d = QVector<char>::fromReadOnlyData("ABCDEFGHIJ"); + QCOMPARE(d.size(), 10u + 1u); + for (int i = 0; i < 10; ++i) + QCOMPARE(d.data()[i], char('A' + i)); + } + + { + // wchar_t is not necessarily 2-bytes + QVector<wchar_t> d = QVector<wchar_t>::fromReadOnlyData(L"ABCDEFGHIJ"); + QCOMPARE(d.size(), 10u + 1u); + for (int i = 0; i < 10; ++i) + QCOMPARE(d.data()[i], wchar_t('A' + i)); + QVERIFY(d.isDetached()); + } + + { + const char data[] = "ABCDEFGHIJ"; + const QVector<char> v = QVector<char>::fromReadOnlyData(data); + + QVERIFY(v.constData() == data); + QVERIFY(!v.isEmpty()); + QCOMPARE(v.size(), size_t(11)); + // v.capacity() is unspecified, for now + + QCOMPARE((void*)(const char*)(v.constBegin() + v.size()), (void*)(const char*)v.constEnd()); + + for (int i = 0; i < 10; ++i) + QCOMPARE(v[i], char('A' + i)); + QCOMPARE(v[10], char('\0')); + } + + { + struct LiteralType { + int value; + Q_DECL_CONSTEXPR LiteralType(int v = 0) : value(v) {} + }; + const LiteralType literal[] = {LiteralType(0), LiteralType(1), LiteralType(2)}; + + const QVector<LiteralType> d = QVector<LiteralType>::fromReadOnlyData(literal); + QCOMPARE(d.size(), 3); + for (int i = 0; i < 3; ++i) + QCOMPARE(d.data()[i].value, i); + } +} + QTEST_MAIN(tst_QList) #include "tst_qlist.moc" diff --git a/tests/auto/tools/qmakelib/tst_qmakelib.cpp b/tests/auto/tools/qmakelib/tst_qmakelib.cpp index 3d66f940ff..a699a0575e 100644 --- a/tests/auto/tools/qmakelib/tst_qmakelib.cpp +++ b/tests/auto/tools/qmakelib/tst_qmakelib.cpp @@ -56,7 +56,7 @@ void tst_qmakelib::cleanupTestCase() void tst_qmakelib::proString() { - QString qs1(QStringLiteral("this is a string")); + QString qs1(QString::fromUtf8("this is a string")); ProString s1(qs1); QCOMPARE(s1.toQString(), QStringLiteral("this is a string")); |