diff options
author | Marc Mutz <marc.mutz@qt.io> | 2022-07-18 09:47:29 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2022-07-21 14:54:25 +0000 |
commit | db09fec6a1e08b05cd832a68e90857376c8e914e (patch) | |
tree | 9b22e70705d2073bbc4eb40683e119dad1edc64a /src/corelib/text | |
parent | 2d6ca88512f9e318491c502f6f97d2e853ffca4a (diff) |
QByteDataBuffer: avoid silent failures of read(n)
On 32-bit platforms, the user can ask for more than INT_MAX bytes to
be returned from read(n), by way of its qint64 argument. We can, of
course, not return so much data because allocation would fail, so fail
early, by detecting this situation and do what resize() would have done
if it was not for the narrowing of its argument: throw bad_alloc.
Reviewers may ask themselves whether byteAmount(), which already caps
the request, would not have physically limited the request size to
INT_MAX, since we cannot possibly hold more data than that on 32-bit
platforms. But this is not correct, since QByteDataBuffer is
essentially a list of QByteArrays, and those can be shared copies of
each other (which isn't uncommon, if you consider how a user of the
class may be piecing together data by reusing existing QByteArrays).
The read(n) and readAll() functions are already documented to be
inefficient and should-not-use, we may want to remove them in the
future to force users to think about this problem in the context of
their domain.
Pick-to: 6.4
Change-Id: Ia152db0a1fc65bbef35acd463f12fba1b7726d4a
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/corelib/text')
-rw-r--r-- | src/corelib/text/qbytedata_p.h | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/corelib/text/qbytedata_p.h b/src/corelib/text/qbytedata_p.h index 67a39eb742..819dd46315 100644 --- a/src/corelib/text/qbytedata_p.h +++ b/src/corelib/text/qbytedata_p.h @@ -19,6 +19,8 @@ #include <qbytearray.h> #include <QtCore/qlist.h> +#include <climits> + QT_BEGIN_NAMESPACE // this class handles a list of QByteArrays. It is a variant of QRingBuffer @@ -120,8 +122,15 @@ public: inline QByteArray read(qint64 amount) { amount = qMin(byteAmount(), amount); + if constexpr (sizeof(qsizetype) == sizeof(int)) { // 32-bit + // While we cannot overall have more than INT_MAX memory allocated, + // the QByteArrays we hold may be shared copies of each other, + // causing byteAmount() to exceed INT_MAX. + if (amount > INT_MAX) + qBadAlloc(); // what resize() would do if it saw past the truncation + } QByteArray byteData; - byteData.resize(amount); + byteData.resize(qsizetype(amount)); read(byteData.data(), byteData.size()); return byteData; } |