summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization/qdatastream.cpp
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2024-04-26 17:25:25 +0200
committerIvan Solovev <ivan.solovev@qt.io>2024-05-02 19:03:42 +0200
commite176dd78fd2f253eb2625585b2bd90b5713e5984 (patch)
treea39fa10d2564968c5c73ff6f02eb34c19ef66287 /src/corelib/serialization/qdatastream.cpp
parentb02798095d66bb9c2d81652b2c4f287b128b24ee (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.cpp18
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;