diff options
| author | Ivan Solovev <ivan.solovev@qt.io> | 2024-04-26 17:25:25 +0200 |
|---|---|---|
| committer | Ivan Solovev <ivan.solovev@qt.io> | 2024-05-02 19:03:42 +0200 |
| commit | e176dd78fd2f253eb2625585b2bd90b5713e5984 (patch) | |
| tree | a39fa10d2564968c5c73ff6f02eb34c19ef66287 /src/corelib/serialization/qdatastream.cpp | |
| parent | b02798095d66bb9c2d81652b2c4f287b128b24ee (diff) | |
QDataStream::readBytes: do not leak the memory in case of bad_alloc
The algorithm was leaking the previous buffer if the attempt to
allocate a new one failed with std::bad_alloc.
Wrap the buffer allocations into std::unique_ptr, so that we do
not leak the buffer in case of bad_alloc.
This patch is not changing the behavior of QDataStream, so it's
NOT handling the bad_alloc exception, and also does not change
the state of the buffer in case the exception occurs.
Pick-to: 6.7 6.5
Change-Id: I5558a6d03768094e4ee83ca47cacf4e09c36f1cf
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/corelib/serialization/qdatastream.cpp')
| -rw-r--r-- | src/corelib/serialization/qdatastream.cpp | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp index d35e871de0d..6dcc0890e32 100644 --- a/src/corelib/serialization/qdatastream.cpp +++ b/src/corelib/serialization/qdatastream.cpp @@ -1088,26 +1088,20 @@ QDataStream &QDataStream::readBytes(char *&s, qint64 &l) qsizetype step = (dev->bytesAvailable() >= len) ? len : 1024 * 1024; qsizetype allocated = 0; - char *prevBuf = nullptr; - char *curBuf = nullptr; + std::unique_ptr<char[]> curBuf = nullptr; do { qsizetype blockSize = qMin(step, len - allocated); - prevBuf = curBuf; - curBuf = new char[allocated + blockSize + 1]; - if (prevBuf) { - memcpy(curBuf, prevBuf, allocated); - delete [] prevBuf; - } - if (readBlock(curBuf + allocated, blockSize) != blockSize) { - delete [] curBuf; + const qsizetype n = allocated + blockSize + 1; + if (const auto prevBuf = std::exchange(curBuf, std::make_unique<char[]>(n))) + memcpy(curBuf.get(), prevBuf.get(), allocated); + if (readBlock(curBuf.get() + allocated, blockSize) != blockSize) return *this; - } allocated += blockSize; step *= 2; } while (allocated < len); - s = curBuf; + s = curBuf.release(); s[len] = '\0'; l = len; return *this; |
