Fix UB in QIODevicePrivate

Passing nullptr as the second argument of memcpy/memmove
constitutes undefined behavior, even if the length argument
is zero at the same time.

Fix by protecting mem{cpy,move,chr} from nullptrs.

Found by UBSan:
  qtbase/src/corelib/io/qiodevice_p.h:105:33: runtime error: null pointer passed as argument 2, which is declared to never be null
  qtbase/src/corelib/io/qiodevice_p.h:175:53: runtime error: null pointer passed as argument 2, which is declared to never be null

Change-Id: I979158b0a74169ca4eb459928398ebc40f77dfb5
Reviewed-by: Alex Trotsenko <alex1973tr@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Marc Mutz 2016-01-06 10:36:41 +01:00
parent 13189360e5
commit 61169b72c2
1 changed files with 10 additions and 6 deletions

View File

@ -102,14 +102,17 @@ public:
}
qint64 read(char* target, qint64 size) {
qint64 r = qMin(size, len);
memcpy(target, first, r);
len -= r;
first += r;
if (r) {
memcpy(target, first, r);
len -= r;
first += r;
}
return r;
}
qint64 peek(char* target, qint64 size) {
qint64 r = qMin(size, len);
memcpy(target, first, r);
if (r)
memcpy(target, first, r);
return r;
}
char* reserve(qint64 size) {
@ -141,7 +144,7 @@ public:
return r;
}
bool canReadLine() const {
return memchr(first, '\n', len);
return first && memchr(first, '\n', len);
}
void ungetChar(char c) {
if (first == buf) {
@ -172,7 +175,8 @@ private:
if (newCapacity > capacity) {
// allocate more space
char* newBuf = new char[newCapacity];
memmove(newBuf + moveOffset, first, len);
if (first)
memmove(newBuf + moveOffset, first, len);
delete [] buf;
buf = newBuf;
capacity = newCapacity;