[PATCH v2 0/2] MR10382: comctl32/imagelist: Limit maximum image count.
Some applications mistakenly use a very large initial image count. On Windows, there is no limit on how large an imagelist can be. This makes sure that the GDI handle limit will be reached before hitting the imagelist limit. Supersedes https://gitlab.winehq.org/wine/wine/-/merge_requests/10059 -- v2: comctl32/imagelist: Limit the initial image count. https://gitlab.winehq.org/wine/wine/-/merge_requests/10382
From: Kun Yang <yangkun@uniontech.com> Signed-off-by: Kun Yang <yangkun@uniontech.com> --- dlls/comctl32/tests/imagelist.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index 68ad0ce7a4c..c2b04f622a4 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -2204,6 +2204,8 @@ static void test_iconsize(void) static void test_create_destroy(void) { HIMAGELIST himl; + IMAGEINFO info; + HBITMAP hbm; INT cx, cy; BOOL rc; INT ret; @@ -2263,6 +2265,19 @@ static void test_create_destroy(void) ok(himl == NULL, "got %p\n", himl); himl = pImageList_Create(1, -1, ILC_COLORDDB, 4, 4); ok(himl == NULL, "got %p\n", himl); + + /* Test creating an imagelist with an excessively large initial image count */ + himl = pImageList_Create(32, 32, ILC_COLOR32, 0xc0c0c0, 10); + ok(himl != NULL, "got %p\n", himl); + hbm = create_bitmap(32, 32, 0, ""); + ret = pImageList_Add(himl, hbm, NULL); + ok(ret != -1, "Failed to add an image.\n"); + ret = pImageList_GetImageInfo(himl, 0, &info); + ok(ret, "got %d\n", ret); + todo_wine + ok(info.hbmImage != NULL, "got %p\n", info.hbmImage); + DeleteObject(hbm); + pImageList_Destroy(himl); } static void check_color_table(const char *name, HDC hdc, HIMAGELIST himl, UINT ilc, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10382
From: Zhiyi Zhang <zzhang@codeweavers.com> Some applications mistakenly use a very large initial image count, for example, 0xc0c0c0. Treat the user specified initial image count only as a suggestion and use something reasonable when such cases happen. 256 initial images should be enough for most cases. Otherwise, CreateDIBSection() fails to create the internal bitmap due to invalid image dimensions. This doesn't change how large an image list can grow. --- dlls/comctl32/imagelist.c | 3 +++ dlls/comctl32/tests/imagelist.c | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c index ba340645db8..6650e3db04b 100644 --- a/dlls/comctl32/imagelist.c +++ b/dlls/comctl32/imagelist.c @@ -3663,6 +3663,9 @@ static HRESULT WINAPI ImageListImpl_Initialize(IImageList2 *iface, INT cx, INT c grow = 256; } + /* Some applications mistakenly use a very large initial image count. Limit it to something reasonable */ + initial = min(initial, 256); + himl->cx = cx; himl->cy = cy; himl->flags = flags; diff --git a/dlls/comctl32/tests/imagelist.c b/dlls/comctl32/tests/imagelist.c index c2b04f622a4..1921567627f 100644 --- a/dlls/comctl32/tests/imagelist.c +++ b/dlls/comctl32/tests/imagelist.c @@ -2274,7 +2274,6 @@ static void test_create_destroy(void) ok(ret != -1, "Failed to add an image.\n"); ret = pImageList_GetImageInfo(himl, 0, &info); ok(ret, "got %d\n", ret); - todo_wine ok(info.hbmImage != NULL, "got %p\n", info.hbmImage); DeleteObject(hbm); pImageList_Destroy(himl); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10382
v2: Limit the initial image count to 256. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10382#note_132930
On Fri Mar 20 08:13:15 2026 +0000, Zhiyi Zhang wrote:
v2: Limit the initial image count to 256. Adding some tests for Write/Load shows that it's behaving weirder than it needs to. For some combinations it's setting cMaxImage lower than current image count. Might be some estimation based on "some" memory allowance divided by individual image size. Also, cMaxImage is serialized as 16 bit int, same for current count, so arguments larger than that are already out of bounds probably. This behavior is also different on v6, where it seems to store argument value as is (unless there is something going on with our tests on v6).
Anyway, this does not look important to spend time on. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10382#note_132955
This merge request was approved by Nikolay Sivov. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10382
participants (4)
-
Kun Yang -
Nikolay Sivov (@nsivov) -
Zhiyi Zhang -
Zhiyi Zhang (@zhiyi)