From 6e58122cca6487f8e1f9839d66b72fd1658dc607 Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Tue, 23 Jan 2024 16:39:38 +0100 Subject: [PATCH] QDataStream: add a new SizeLimitExceeded status code This status is supposed to be used when the stream tries to read or write more data than it is supported by the current platform. For example, reading more than 2 GiB of data on a 32-bit platform will result into this status, but it will work fine on a 64-bit platform. This patch uses the new status in read operations. Amends fd48ce0b73c74dafd5db27bc1f2752ef665df7ef Found in 6.7 API review Change-Id: I675b1ee25fafba174ce8f94c3470dbb7893d6d9e Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira (cherry picked from commit 36cc9fc54a1b581e5fd9377e0ddbcd1670ab447f) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/serialization/qdatastream.cpp | 7 ++++++- src/corelib/serialization/qdatastream.h | 9 +++++---- src/corelib/text/qbytearray.cpp | 2 +- src/corelib/text/qstring.cpp | 2 +- .../serialization/qdatastream/tst_qdatastream.cpp | 4 ++-- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp index 171d29f529c..008edc088a0 100644 --- a/src/corelib/serialization/qdatastream.cpp +++ b/src/corelib/serialization/qdatastream.cpp @@ -222,6 +222,11 @@ QT_BEGIN_NAMESPACE data in the underlying device. \value ReadCorruptData The data stream has read corrupt data. \value WriteFailed The data stream cannot write to the underlying device. + \value [since 6.7] SizeLimitExceeded The data stream cannot read or write + the data because its size is larger than supported + by the current platform. This can happen, for + example, when trying to read more that 2 GiB of + data on a 32-bit platform. */ /***************************************************************************** @@ -1064,7 +1069,7 @@ QDataStream &QDataStream::readBytes(char *&s, qsizetype &l) qsizetype len = qsizetype(length); if (length != len || length < 0) { - setStatus(ReadCorruptData); // Cannot store len in l + setStatus(SizeLimitExceeded); // Cannot store len in l return *this; } diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h index 80fd2715961..90d7c9d9da2 100644 --- a/src/corelib/serialization/qdatastream.h +++ b/src/corelib/serialization/qdatastream.h @@ -101,7 +101,8 @@ public: Ok, ReadPastEnd, ReadCorruptData, - WriteFailed + WriteFailed, + SizeLimitExceeded, }; enum FloatingPointPrecision { @@ -267,7 +268,7 @@ QDataStream &readArrayBasedContainer(QDataStream &s, Container &c) qint64 size = QDataStream::readQSizeType(s); qsizetype n = size; if (size != n || size < 0) { - s.setStatus(QDataStream::ReadCorruptData); + s.setStatus(QDataStream::SizeLimitExceeded); return s; } c.reserve(n); @@ -293,7 +294,7 @@ QDataStream &readListBasedContainer(QDataStream &s, Container &c) qint64 size = QDataStream::readQSizeType(s); qsizetype n = size; if (size != n || size < 0) { - s.setStatus(QDataStream::ReadCorruptData); + s.setStatus(QDataStream::SizeLimitExceeded); return s; } for (qsizetype i = 0; i < n; ++i) { @@ -318,7 +319,7 @@ QDataStream &readAssociativeContainer(QDataStream &s, Container &c) qint64 size = QDataStream::readQSizeType(s); qsizetype n = size; if (size != n || size < 0) { - s.setStatus(QDataStream::ReadCorruptData); + s.setStatus(QDataStream::SizeLimitExceeded); return s; } for (qsizetype i = 0; i < n; ++i) { diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index 69d21cbe24d..e48b9bcac1e 100644 --- a/src/corelib/text/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -3312,7 +3312,7 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba) qsizetype len = size; if (size != len || size < -1) { ba.clear(); - in.setStatus(QDataStream::ReadCorruptData); + in.setStatus(QDataStream::SizeLimitExceeded); return in; } if (len == -1) { // null byte-array diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 5dceb2c3e31..aa07223860f 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -9375,7 +9375,7 @@ QDataStream &operator>>(QDataStream &in, QString &str) qsizetype bytes = size; if (size != bytes || size < -1) { str.clear(); - in.setStatus(QDataStream::ReadCorruptData); + in.setStatus(QDataStream::SizeLimitExceeded); return in; } if (bytes == -1) { // null string diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index 22bcba5ef13..8051924dcec 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -2904,10 +2904,10 @@ void tst_QDataStream::status_QString_data() QTest::newRow("32 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfc", 4) << (int) QDataStream::ReadPastEnd << QString(); #else // too big for 32 bit platforms - QTest::newRow("32 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfc", 4) << (int) QDataStream::ReadCorruptData << QString(); + QTest::newRow("32 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfc", 4) << (int) QDataStream::SizeLimitExceeded << QString(); #endif // too big on both 32 and 64 bit platforms because qsizetype is signed - QTest::newRow("64 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xfe", 12) << (int) QDataStream::ReadCorruptData << QString(); + QTest::newRow("64 bit size MAX string no content") << QByteArray("\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xfe", 12) << (int) QDataStream::SizeLimitExceeded << QString(); // corrupt data because QChar is 16 bit => even size required QTest::newRow("corrupt1") << QByteArray("yyyy") << (int) QDataStream::ReadCorruptData << QString();