diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2016-06-07 16:52:13 +0200 |
---|---|---|
committer | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2016-06-15 12:55:16 +0000 |
commit | c2b7841843f05fe902e6a94aee2c3f33b169009e (patch) | |
tree | 814eb9c5747abfa650951b0bf2ce720a3ffc099d /tests | |
parent | c165cbaef2ccff52225836baf3c3db64ebe128dc (diff) |
Finally fix crash in inplace-modified data-constructed images
Avoid all inplace modification of images using external data
buffers. Since the QImage methods are documented to create a
(modified) copy, there is afterwards no API requirement on the
lifetime of the data buffer.
This patch supersedes 509bc7e59c69937900cf258e64889a6e88edbcf0
Task-number: QTBUG-53721
Change-Id: I3ccc01619eb61d8630104449394e0b76df0af695
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/gui/image/qimage/tst_qimage.cpp | 74 |
1 files changed, 70 insertions, 4 deletions
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index e8e1cd1896..435178a885 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -2447,6 +2447,35 @@ void tst_QImage::inplaceRgbSwapped() } QCOMPARE(imageSwapped.constScanLine(0), orginalPtr); + + for (int rw = 0; rw <= 1; rw++) { + // Test attempted inplace conversion of images created on existing buffer + uchar *volatileData = 0; + QImage orig = imageSwapped; + QImage dataSwapped; + { + QVERIFY(!orig.isNull()); + volatileData = new uchar[orig.byteCount()]; + memcpy(volatileData, orig.constBits(), orig.byteCount()); + + QImage dataImage; + if (rw) + dataImage = QImage(volatileData, orig.width(), orig.height(), orig.format()); + else + dataImage = QImage((const uchar *)volatileData, orig.width(), orig.height(), orig.format()); + + if (orig.colorCount()) + dataImage.setColorTable(orig.colorTable()); + + dataSwapped = std::move(dataImage).rgbSwapped(); + QVERIFY(!dataSwapped.isNull()); + delete[] volatileData; + } + + QVERIFY2(dataSwapped.constBits() != volatileData, rw ? "non-const" : "const"); + QCOMPARE(dataSwapped, orig.rgbSwapped()); + } + #endif } @@ -2529,6 +2558,35 @@ void tst_QImage::inplaceMirrored() } } QCOMPARE(imageMirrored.constScanLine(0), originalPtr); + + for (int rw = 0; rw <= 1; rw++) { + // Test attempted inplace conversion of images created on existing buffer + uchar *volatileData = 0; + QImage orig = imageMirrored; + QImage dataSwapped; + { + QVERIFY(!orig.isNull()); + volatileData = new uchar[orig.byteCount()]; + memcpy(volatileData, orig.constBits(), orig.byteCount()); + + QImage dataImage; + if (rw) + dataImage = QImage(volatileData, orig.width(), orig.height(), orig.format()); + else + dataImage = QImage((const uchar *)volatileData, orig.width(), orig.height(), orig.format()); + + if (orig.colorCount()) + dataImage.setColorTable(orig.colorTable()); + + dataSwapped = std::move(dataImage).mirrored(swap_horizontal, swap_vertical); + QVERIFY(!dataSwapped.isNull()); + delete[] volatileData; + } + + QVERIFY2(dataSwapped.constBits() != volatileData, rw ? "non-const" : "const"); + QCOMPARE(dataSwapped, orig.mirrored(swap_horizontal, swap_vertical)); + } + #endif } @@ -2680,16 +2738,24 @@ void tst_QImage::inplaceRgbConversion() static const quint32 readOnlyData[] = { 0xff0102ffU, 0xff0506ffU, 0xff0910ffU, 0xff1314ffU }; quint32 readWriteData[] = { 0xff0102ffU, 0xff0506ffU, 0xff0910ffU, 0xff1314ffU }; - QImage roImage((const uchar *)readOnlyData, 2, 2, format); - QImage roInplaceConverted = std::move(roImage).convertToFormat(dest_format); + QImage roInplaceConverted; + QImage rwInplaceConverted; + + { + QImage roImage((const uchar *)readOnlyData, 2, 2, format); + roInplaceConverted = std::move(roImage).convertToFormat(dest_format); - QImage rwImage((uchar *)readWriteData, 2, 2, format); - QImage rwInplaceConverted = std::move(rwImage).convertToFormat(dest_format); + QImage rwImage((uchar *)readWriteData, 2, 2, format); + rwInplaceConverted = std::move(rwImage).convertToFormat(dest_format); + } QImage roImage2((const uchar *)readOnlyData, 2, 2, format); QImage normalConverted = roImage2.convertToFormat(dest_format); + QVERIFY(roInplaceConverted.constBits() != (const uchar *)readOnlyData); QCOMPARE(normalConverted, roInplaceConverted); + + QVERIFY(rwInplaceConverted.constBits() != (const uchar *)readWriteData); QCOMPARE(normalConverted, rwInplaceConverted); } #endif |