The frame index should be strictly less than idCount. Previously, an index equal to idCount was not rejected, leading to an out-of-range access.
Signed-off-by: chenzhengyong chenzhengyong@uniontech.com
Although this bug was not fatal because subsequent IStream_Read and related functions also perform boundary checks, it is better to catch the invalid index early for clarity and consistency.
-- v2: windowscodecs: Fix off-by-one check in IcoDecoder_GetFrame.
From: chenzhengyong chenzhengyong@uniontech.com
The frame index should be strictly less than idCount. Previously, an index equal to idCount was not rejected, leading to an out-of-range access.
Signed-off-by: chenzhengyong chenzhengyong@uniontech.com --- dlls/windowscodecs/icoformat.c | 2 +- dlls/windowscodecs/tests/icoformat.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/windowscodecs/icoformat.c b/dlls/windowscodecs/icoformat.c index ae2ae115e5e..c6bc79d852e 100644 --- a/dlls/windowscodecs/icoformat.c +++ b/dlls/windowscodecs/icoformat.c @@ -662,7 +662,7 @@ static HRESULT WINAPI IcoDecoder_GetFrame(IWICBitmapDecoder *iface, goto fail; }
- if (This->header.idCount < index) + if (This->header.idCount <= index) { hr = E_INVALIDARG; goto fail; diff --git a/dlls/windowscodecs/tests/icoformat.c b/dlls/windowscodecs/tests/icoformat.c index 32bde262c88..8b9016b57f1 100644 --- a/dlls/windowscodecs/tests/icoformat.c +++ b/dlls/windowscodecs/tests/icoformat.c @@ -140,6 +140,7 @@ static void test_ico_data_(void *data, DWORD data_size, HRESULT init_hr, int tod HRESULT hr; IWICStream *icostream; IWICBitmapFrameDecode *framedecode = NULL; + UINT count;
hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory); @@ -169,6 +170,11 @@ static void test_ico_data_(void *data, DWORD data_size, HRESULT init_hr, int tod
if (SUCCEEDED(hr)) { + hr = IWICBitmapDecoder_GetFrameCount(decoder, &count); + ok(hr == S_OK, "GetFrameCount failed, hr=%lx\n", hr); + ok(count == 1, "Expected 1 frame, got %u\n", count); + hr = IWICBitmapDecoder_GetFrame(decoder, count, &framedecode); + ok(hr == E_INVALIDARG, "Expected E_INVALIDARG from GetFrame, got %lx\n", hr); hr = IWICBitmapDecoder_GetFrame(decoder, 0, &framedecode); ok(hr == S_OK, "GetFrame failed, hr=%lx\n", hr); }
On Tue Nov 4 01:38:12 2025 +0000, zhengyong chen wrote:
This won’t lead to a bug, as subsequent `IStream_Read` and related functions also include boundary checks. However, since boundary validation is necessary, it would be better to handle it correctly from the beginning.
I added a test case for this kind of boundary check issue.
Nikolay, I don't see why? I don't have a problem with more tests, but to me this seems like a case that should obviously be an error.
In this case it's trivial to test, and I thought there is no harm in that. But I see your point, sorry for the noise.