From 975ebdc4ab77d1c0d8bc91e393eca7095a5d8742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 24 Aug 2012 10:53:58 +0200 Subject: Don't manipulate immutable data QArrayData can point to data it does not own (cf. fromRawData()), which shouldn't be modified. Not even upon destruction, as this data can live in Read-Only memory or be otherwise shared outside the QArrayData realm. Change-Id: I8bdf3050a17802fb003b77d5f543fe31769a7710 Reviewed-by: Thiago Macieira Reviewed-by: Andreas Hartmetz --- .../corelib/tools/qarraydata/tst_qarraydata.cpp | 88 +++++++++++++++++----- 1 file changed, 71 insertions(+), 17 deletions(-) (limited to 'tests/auto') diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp index dea777d652..437c8e25ed 100644 --- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp +++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp @@ -84,6 +84,7 @@ private slots: void arrayOps2(); void setSharable_data(); void setSharable(); + void fromRawData_data(); void fromRawData(); void literals(); void variadicLiterals(); @@ -1421,53 +1422,106 @@ void tst_QArrayData::setSharable() QVERIFY(array->ref.isSharable()); } -void tst_QArrayData::fromRawData() +struct ResetOnDtor +{ + ResetOnDtor() + : value_() + { + } + + ResetOnDtor(int value) + : value_(value) + { + } + + ~ResetOnDtor() + { + value_ = 0; + } + + int value_; +}; + +bool operator==(const ResetOnDtor &lhs, const ResetOnDtor &rhs) +{ + return lhs.value_ == rhs.value_; +} + +template +void fromRawData_impl() { - static const int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + static const T array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; { // Default: Immutable, sharable - SimpleVector raw = SimpleVector::fromRawData(array, + SimpleVector raw = SimpleVector::fromRawData(array, sizeof(array)/sizeof(array[0]), QArrayData::Default); QCOMPARE(raw.size(), size_t(11)); - QCOMPARE((const int *)raw.constBegin(), array); - QCOMPARE((const int *)raw.constEnd(), (const int *)(array + sizeof(array)/sizeof(array[0]))); + QCOMPARE((const T *)raw.constBegin(), array); + QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0]))); QVERIFY(!raw.isShared()); - QVERIFY(SimpleVector(raw).isSharedWith(raw)); + QVERIFY(SimpleVector(raw).isSharedWith(raw)); QVERIFY(!raw.isShared()); // Detach - QCOMPARE(raw.back(), 11); - QVERIFY((const int *)raw.constBegin() != array); + QCOMPARE(raw.back(), T(11)); + QVERIFY((const T *)raw.constBegin() != array); } { // Immutable, unsharable - SimpleVector raw = SimpleVector::fromRawData(array, + SimpleVector raw = SimpleVector::fromRawData(array, sizeof(array)/sizeof(array[0]), QArrayData::Unsharable); QCOMPARE(raw.size(), size_t(11)); - QCOMPARE((const int *)raw.constBegin(), array); - QCOMPARE((const int *)raw.constEnd(), (const int *)(array + sizeof(array)/sizeof(array[0]))); + QCOMPARE((const T *)raw.constBegin(), array); + QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0]))); - SimpleVector copy(raw); + SimpleVector copy(raw); QVERIFY(!copy.isSharedWith(raw)); QVERIFY(!raw.isShared()); QCOMPARE(copy.size(), size_t(11)); - for (size_t i = 0; i < 11; ++i) + for (size_t i = 0; i < 11; ++i) { QCOMPARE(const_(copy)[i], const_(raw)[i]); + QCOMPARE(const_(copy)[i], T(i + 1)); + } QCOMPARE(raw.size(), size_t(11)); - QCOMPARE((const int *)raw.constBegin(), array); - QCOMPARE((const int *)raw.constEnd(), (const int *)(array + sizeof(array)/sizeof(array[0]))); + QCOMPARE((const T *)raw.constBegin(), array); + QCOMPARE((const T *)raw.constEnd(), (const T *)(array + sizeof(array)/sizeof(array[0]))); // Detach - QCOMPARE(raw.back(), 11); - QVERIFY((const int *)raw.constBegin() != array); + QCOMPARE(raw.back(), T(11)); + QVERIFY((const T *)raw.constBegin() != array); + } +} + +void tst_QArrayData::fromRawData_data() +{ + QTest::addColumn("type"); + + QTest::newRow("int") << 0; + QTest::newRow("ResetOnDtor") << 1; +} +void tst_QArrayData::fromRawData() +{ + QFETCH(int, type); + + switch (type) + { + case 0: + fromRawData_impl(); + break; + case 1: + fromRawData_impl(); + break; + + default: + QFAIL("Unexpected type data"); } } -- cgit v1.2.3