diff options
Diffstat (limited to 'tests/auto/corelib/serialization/qcborvalue')
-rw-r--r-- | tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro | 2 | ||||
-rw-r--r-- | tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp | 68 |
2 files changed, 55 insertions, 15 deletions
diff --git a/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro b/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro index 9dd67da1f0..4d01b290f5 100644 --- a/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro +++ b/tests/auto/corelib/serialization/qcborvalue/qcborvalue.pro @@ -1,4 +1,4 @@ -QT = core testlib +QT = core-private testlib TARGET = tst_qcborvalue CONFIG += testcase SOURCES += \ diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 49bb9cc144..6d8161c1f9 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2020 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -40,6 +40,8 @@ #include <QtCore/qcborvalue.h> #include <QtTest> +#include <QtCore/private/qbytearray_p.h> + Q_DECLARE_METATYPE(QCborKnownTags) Q_DECLARE_METATYPE(QCborValue) Q_DECLARE_METATYPE(QCborValue::EncodingOptions) @@ -102,6 +104,8 @@ private slots: void fromCborStreamReaderIODevice(); void validation_data(); void validation(); + void hugeDeviceValidation_data(); + void hugeDeviceValidation(); void recursionLimit_data(); void recursionLimit(); void toDiagnosticNotation_data(); @@ -1689,39 +1693,75 @@ void tst_QCborValue::fromCborStreamReaderIODevice() fromCbor_common(doCheck); } +#include "../cborlargedatavalidation.cpp" + void tst_QCborValue::validation_data() { + // Add QCborStreamReader-specific limitations due to use of QByteArray and + // QString, which are allocated by QArrayData::allocate(). + const qsizetype MaxInvalid = std::numeric_limits<QByteArray::size_type>::max(); + const qsizetype MinInvalid = MaxByteArraySize + 1; addValidationColumns(); - addValidationData(); + addValidationData(MinInvalid); + addValidationLargeData(MinInvalid, MaxInvalid); // These tests say we have arrays and maps with very large item counts. // They are meant to ensure we don't pre-allocate a lot of memory // unnecessarily and possibly crash the application. The actual number of // elements in the stream is only 2, so we should get an unexpected EOF - // error. QCborValue internally uses 16 bytes per element, so we get to - // 2 GB at 2^27 elements. - QTest::addRow("very-large-array-no-overflow") << raw("\x9a\x07\xff\xff\xff" "\0\0"); - QTest::addRow("very-large-array-overflow1") << raw("\x9a\x40\0\0\0" "\0\0"); - - // this makes sure we don't accidentally clip to 32-bit: sending 2^32+2 elements - QTest::addRow("very-large-array-overflow2") << raw("\x9b\0\0\0\1""\0\0\0\2" "\0\0"); + // error. QCborValue internally uses 16 bytes per element, so we get to 2 + // GB at 2^27 elements (32-bit) or, theoretically, 2^63 bytes at 2^59 + // elements (64-bit). + if (sizeof(QVector<int>::size_type) == sizeof(int)) { + // 32-bit sizes (Qt 5 and 32-bit platforms) + QTest::addRow("very-large-array-no-overflow") << raw("\x9a\x07\xff\xff\xff" "\0\0") << 0 << CborErrorUnexpectedEOF; + QTest::addRow("very-large-array-overflow1") << raw("\x9a\x40\0\0\0" "\0\0") << 0 << CborErrorUnexpectedEOF; + + // this makes sure we don't accidentally clip to 32-bit: sending 2^32+2 elements + QTest::addRow("very-large-array-overflow2") << raw("\x9b\0\0\0\1""\0\0\0\2" "\0\0") << 0 << CborErrorDataTooLarge; + } else { + // 64-bit Qt 6 + QTest::addRow("very-large-array-no-overflow") << raw("\x9b\x07\xff\xff\xff" "\xff\xff\xff\xff" "\0\0"); + QTest::addRow("very-large-array-overflow") << raw("\x9b\x40\0\0\0" "\0\0\0\0" "\0\0"); + } } void tst_QCborValue::validation() { QFETCH(QByteArray, data); + QFETCH(CborError, expectedError); + QCborError error = { QCborError::Code(expectedError) }; - QCborParserError error; - QCborValue decoded = QCborValue::fromCbor(data, &error); - QVERIFY(error.error != QCborError{}); + QCborParserError parserError; + QCborValue decoded = QCborValue::fromCbor(data, &parserError); + QCOMPARE(parserError.error, error); if (data.startsWith('\x81')) { // decode without the array prefix - decoded = QCborValue::fromCbor(data.mid(1), &error); - QVERIFY(error.error != QCborError{}); + char *ptr = const_cast<char *>(data.constData()); + QByteArray mid = QByteArray::fromRawData(ptr + 1, data.size() - 1); + decoded = QCborValue::fromCbor(mid, &parserError); + QCOMPARE(parserError.error, error); } } +void tst_QCborValue::hugeDeviceValidation_data() +{ + addValidationHugeDevice(MaxByteArraySize + 1, MaxStringSize + 1); +} + +void tst_QCborValue::hugeDeviceValidation() +{ + QFETCH(QSharedPointer<QIODevice>, device); + QFETCH(CborError, expectedError); + QCborError error = { QCborError::Code(expectedError) }; + + device->open(QIODevice::ReadOnly | QIODevice::Unbuffered); + QCborStreamReader reader(device.data()); + QCborValue decoded = QCborValue::fromCbor(reader); + QCOMPARE(reader.lastError(), error); +} + void tst_QCborValue::recursionLimit_data() { constexpr int RecursionAttempts = 4096; |