winrt: Fix memory leak for file reading

IInputStream::ReadAsync might create a separate buffer to fill in data.
Passing a buffer with GetAddressOf() can cause a memory leak of the size
of data to be read.

Instead, pass a separate buffer pointer and continue to use this one
after the async operation. This way, the OS can decide whether to switch
buffers or not, keeping ref counting in sync.

Task-number: QTBUG-52961
Change-Id: I9dfb627287142355ebcf74ca52427b4e8108e8d1
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
bb10
Maurice Kalinowski 2016-04-25 12:29:20 +02:00
parent adac71c044
commit 52e68d4e10
1 changed files with 9 additions and 3 deletions

View File

@ -463,14 +463,20 @@ qint64 QWinRTFileEngine::read(char *data, qint64 maxlen)
hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &op);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
hr = QWinRTFunctions::await(op, buffer.GetAddressOf());
// Quoting MSDN IInputStream::ReadAsync() documentation:
// "Depending on the implementation, the data that's read might be placed
// into the input buffer, or it might be returned in a different buffer."
// Using GetAddressOf can cause ref counting errors leaking the original
// buffer.
ComPtr<IBuffer> effectiveBuffer;
hr = QWinRTFunctions::await(op, effectiveBuffer.GetAddressOf());
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
hr = buffer->get_Length(&length);
hr = effectiveBuffer->get_Length(&length);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
hr = buffer.As(&byteArrayAccess);
hr = effectiveBuffer.As(&byteArrayAccess);
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
byte *bytes;