summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/winrt
diff options
context:
space:
mode:
authorMaurice Kalinowski <maurice.kalinowski@qt.io>2016-04-25 12:29:20 +0200
committerMaurice Kalinowski <maurice.kalinowski@qt.io>2016-04-28 03:40:07 +0000
commit52e68d4e106548eb027d4b35e47c941eb2d73f58 (patch)
tree6e214d113eccd1f522da90ba61dddcb27764d79c /src/plugins/platforms/winrt
parentadac71c04454219bdca79cbace5a1d9c18ce05c4 (diff)
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>
Diffstat (limited to 'src/plugins/platforms/winrt')
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
index 858cb841b9..fb7c5e9990 100644
--- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
@@ -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;