From f12a775b273163065db9de1845b6e9a05f7bbdaf Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Thu, 26 Nov 2020 15:21:24 -0800 Subject: [PATCH] shcore: Return failure on Read past end of memory stream. Signed-off-by: Daniel Lehman Signed-off-by: Alexandre Julliard --- dlls/shcore/main.c | 18 ++++++++------- dlls/shlwapi/tests/istream.c | 55 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/dlls/shcore/main.c b/dlls/shcore/main.c index dc782e8be08..d5fce76eade 100644 --- a/dlls/shcore/main.c +++ b/dlls/shcore/main.c @@ -603,17 +603,19 @@ static HRESULT WINAPI memstream_Read(IStream *iface, void *buff, ULONG buff_size TRACE("(%p)->(%p, %u, %p)\n", stream, buff, buff_size, read_len); if (stream->u.mem.position >= stream->u.mem.length) - length = 0; - else - length = stream->u.mem.length - stream->u.mem.position; - - length = buff_size > length ? length : buff_size; - if (length != 0) /* not at end of buffer and we want to read something */ { - memmove(buff, stream->u.mem.buffer + stream->u.mem.position, length); - stream->u.mem.position += length; /* adjust pointer */ + if (read_len) + *read_len = 0; + return S_FALSE; } + length = stream->u.mem.length - stream->u.mem.position; + if (buff_size < length) + length = buff_size; + + memmove(buff, stream->u.mem.buffer + stream->u.mem.position, length); + stream->u.mem.position += length; + if (read_len) *read_len = length; diff --git a/dlls/shlwapi/tests/istream.c b/dlls/shlwapi/tests/istream.c index d3e7dbb8810..84957ac8cd1 100644 --- a/dlls/shlwapi/tests/istream.c +++ b/dlls/shlwapi/tests/istream.c @@ -736,8 +736,10 @@ static void test_SHCreateMemStream(void) { static const BYTE initial[10]; IStream *stream, *stream2; + LARGE_INTEGER off; IUnknown *unk; char buff[10]; + ULONG i, num; HRESULT hr; stream = SHCreateMemStream(initial, 0); @@ -756,9 +758,56 @@ static void test_SHCreateMemStream(void) if (unk) IUnknown_Release(unk); - hr = IStream_Read(stream, buff, sizeof(buff), NULL); -todo_wine - ok(hr == S_FALSE || broken(hr == S_OK) /* WinXP */, "Unexpected hr %#x.\n", hr); + num = ~0; + hr = IStream_Read(stream, buff, sizeof(buff), &num); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + ok(num == 0, "expected 0, got 0x%08x\n", num); + + num = ~0; + memset(buff, 0x55, sizeof(buff)); + hr = IStream_Write(stream, buff, sizeof(buff), &num); + ok(hr == S_OK, "Failed to write, hr %#x.\n", hr); + ok(num == sizeof(buff), "expected %u, got %u\n", sizeof(buff), num); + + off.QuadPart = 0; + hr = IStream_Seek(stream, off, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Failed to seek, hr %#x.\n", hr); + + num = ~0; + memset(buff, 0, sizeof(buff)); + hr = IStream_Read(stream, buff, sizeof(buff), &num); + ok(hr == S_OK, "Failed to read, hr %#x.\n", hr); + ok(num == sizeof(buff), "expected %u, got %u\n", sizeof(buff), num); + for (i = 0; i < ARRAY_SIZE(buff); i++) + ok(buff[i] == 0x55, "expected 0x55, got 0x%02x at %u\n", buff[i], i); + + num = ~0; + hr = IStream_Read(stream, buff, sizeof(buff), &num); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + ok(num == 0, "expected 0, got 0x%08x\n", num); + + num = ~0; + memset(buff, 0x11, sizeof(buff)); + hr = IStream_Write(stream, buff, sizeof(buff), &num); + ok(hr == S_OK, "Failed to write, hr %#x.\n", hr); + ok(num == sizeof(buff), "expected %u, got %u\n", sizeof(buff), num); + + off.QuadPart = -sizeof(buff); + hr = IStream_Seek(stream, off, STREAM_SEEK_CUR, NULL); + ok(hr == S_OK, "Failed to seek, hr %#x.\n", hr); + + num = ~0; + memset(buff, 0, sizeof(buff)); + hr = IStream_Read(stream, buff, sizeof(buff), &num); + ok(hr == S_OK, "Failed to read, hr %#x.\n", hr); + ok(num == sizeof(buff), "expected %u, got %u\n", sizeof(buff), num); + for (i = 0; i < ARRAY_SIZE(buff); i++) + ok(buff[i] == 0x11, "expected 0x11, got 0x%02x at %u\n", buff[i], i); + + num = ~0; + hr = IStream_Read(stream, buff, sizeof(buff), &num); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + ok(num == 0, "expected 0, got 0x%08x\n", num); hr = IStream_Clone(stream, &stream2); todo_wine -- 2.11.4.GIT