summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2015-04-27 10:32:32 +0200
committerMarc Mutz <marc.mutz@kdab.com>2015-04-28 07:15:51 +0000
commit84b739158d5fdc356e5c6c963ba740fd081db82e (patch)
tree918123cbf2c77776c7cfce095e287f7da94cd4fd
parent39683b2980189bebcb35955eaa6aa0ae7cd353a7 (diff)
QIODevice: fix data loss when reading large amounts from sequential devices
In certain situations, when reading a large amount of data from sequential devices with QIODevice::readAll(), content was lost when passing a qint64 value > QByteArray::MaxSize into QByteArray::resize(), which takes an int. The result of the conversion to int is either negative or calculated mod 2^32. In any case, it will at some point be < QByteArray::size(), which prompts QByteArray to truncate, losing already-read content. Fix by adding an explicit size check before calling QByteArray::resize(). This shows once more that an API that uses int for sizes is dangerous. Esp. on 64-bit platforms. Change-Id: I30fbfad0bf37476c34141b6f3786e7e0fc8e1e74 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
-rw-r--r--src/corelib/io/qiodevice.cpp4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 47484ad596..e73a200fb4 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -989,6 +989,10 @@ QByteArray QIODevice::readAll()
// Size is unknown, read incrementally.
qint64 readResult;
do {
+ if (quint64(readBytes) + QIODEVICE_BUFFERSIZE > QByteArray::MaxSize) {
+ // If resize would fail, don't read more, return what we have.
+ break;
+ }
result.resize(readBytes + QIODEVICE_BUFFERSIZE);
readResult = read(result.data() + readBytes, QIODEVICE_BUFFERSIZE);
if (readResult > 0 || readBytes == 0)