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. Change-Id: Ia152db0a1fc65bbef35acd463f12fba1b7726d4a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit db09fec6a1e08b05cd832a68e90857376c8e914e) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
caa7970df8
commit
a88f62b0c4
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user