From 0985c707a960988cb046b7f810c4cf5788dba30f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 27 Jan 2024 10:38:32 +0100 Subject: [PATCH] QBitArray: don't create invalid Qt 5 streams Qt 5 streams cannot handle QBitArrays with more than INT_MAX bits, even on 64-bit platforms, because of interface constraints (size_type int). Qt 6 can, so make sure to refuse serialization of oversized QBitArrays to Qt-5-compatible streams. [ChangeLog][QtCore][QBitArray] Now refuses to stream a QBitArray with size() > INT_MAX to a Qt-5-compatible QDataStream. Pick-to: 6.6 6.5 6.2 Change-Id: I263e27bd366757c8e0360dfd337948c44d00647a Reviewed-by: Thiago Macieira Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit 9219e8ff1d13a7e9aeb595d60aa4b3767a8941fc) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/tools/qbitarray.cpp | 4 ++++ tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index 249bd11db19..ad097ce543b 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -896,6 +896,10 @@ QDataStream &operator<<(QDataStream &out, const QBitArray &ba) { const qsizetype len = ba.size(); if (out.version() < QDataStream::Qt_6_0) { + if (Q_UNLIKELY(len > qsizetype{(std::numeric_limits::max)()})) { + out.setStatus(QDataStream::WriteFailed); // ### SizeLimitExceeded + return out; + } out << quint32(len); } else { out << quint64(len); diff --git a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp index 7f33c6060bf..21e64246516 100644 --- a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp +++ b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp @@ -94,8 +94,9 @@ void tst_QBitArray::canHandleIntMaxBits() }); try { - constexpr int Size1 = INT_MAX - 2; - constexpr int Size2 = Size1 + 2; + constexpr qsizetype Size1 = sizeof(void*) > sizeof(int) ? qsizetype(INT_MAX) + 2 : + INT_MAX - 2; + constexpr qsizetype Size2 = Size1 + 2; QBitArray ba(Size1, true); QCOMPARE(ba.size(), Size1); @@ -108,6 +109,13 @@ void tst_QBitArray::canHandleIntMaxBits() QCOMPARE(ba.at(Size2 - 1), false); QByteArray serialized; + if constexpr (sizeof(void*) > sizeof(int)) { + QDataStream ds(&serialized, QIODevice::WriteOnly); + ds.setVersion(QDataStream::Qt_5_15); + ds << ba; + QCOMPARE(ds.status(), QDataStream::Status::WriteFailed); // ### SizeLimitExceeded + serialized.clear(); + } { QDataStream ds(&serialized, QIODevice::WriteOnly); ds << ba;