QWindowsPipeReader: fix possible invalid invocation of ReadFileEx()

If the user calls QLocalSocket::setReadBufferSize() with a value less
than the current size of the pipe buffer, startAsyncRead() would call
ReadFileEx() with invalid parameters:

  ReadFileEx(handle, nullptr, some_big_value, ...);

Change-Id: I3d153e3ec34f8038dc001c1c896aeceb666a8979
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Alex Trotsenko 2017-04-28 18:36:04 +03:00
parent 68df0576dd
commit 91c1b5490e
2 changed files with 14 additions and 2 deletions

View File

@ -215,13 +215,13 @@ void QWindowsPipeReader::notified(DWORD errorCode, DWORD numberOfBytesRead)
void QWindowsPipeReader::startAsyncRead()
{
const DWORD minReadBufferSize = 4096;
DWORD bytesToRead = qMax(checkPipeState(), minReadBufferSize);
qint64 bytesToRead = qMax(checkPipeState(), minReadBufferSize);
if (pipeBroken)
return;
if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) {
bytesToRead = readBufferMaxSize - readBuffer.size();
if (bytesToRead == 0) {
if (bytesToRead <= 0) {
// Buffer is full. User must read data from the buffer
// before we can read more from the pipe.
return;

View File

@ -625,6 +625,18 @@ void tst_QLocalSocket::readBufferOverflow()
QCOMPARE(client.read(buffer, readBufferSize), qint64(readBufferSize));
// no more bytes available
QCOMPARE(client.bytesAvailable(), 0);
#ifdef Q_OS_WIN
// Test overflow caused by an asynchronous pipe operation.
client.setReadBufferSize(1);
serverSocket->write(buffer, 2);
QVERIFY(client.waitForReadyRead());
// socket disconnects, if there any error on pipe
QCOMPARE(client.state(), QLocalSocket::ConnectedState);
QCOMPARE(client.bytesAvailable(), qint64(2));
QCOMPARE(client.read(buffer, 2), qint64(2));
#endif
}
static qint64 writeCommand(const QVariant &command, QIODevice *device, int commandCounter)