From 53ddb4a4da7c47f7f2bbba1ee3bb56d9b3d58283 Mon Sep 17 00:00:00 2001 From: Heiko Klare Date: Mon, 25 Aug 2025 11:52:32 +0200 Subject: [PATCH] [Win32] Clean up disposed images when retrieving image list handle #2432 Images inside an ImageList may become disposed. For that reason, methods like indexOf() or add() check for the images inside the list being disposed to null them. This check is missing in the getHandle() method used when requesting the ImageList handle for a different zoom, which can lead to exceptions because of access to a disposed Image instance. This change adapts the ImageList implementation to always consider that an image inside the list may have been disposed. The according cleanup logic is factored out from all places. Fixes https://github.com/eclipse-platform/eclipse.platform.swt/issues/2432 --- .../org/eclipse/swt/internal/ImageList.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java index 0b8f2525a0a..3ad2ad43c26 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java @@ -51,10 +51,8 @@ public int add (Image image) { int count = OS.ImageList_GetImageCount (handle); int index = 0; while (index < count) { - if (images [index] != null) { - if (images [index].isDisposed ()) images [index] = null; - } - if (images [index] == null) break; + Image imageAtIndex = getOrClearIfDisposed(index); + if (imageAtIndex == null) break; index++; } if (count == 0) { @@ -71,6 +69,13 @@ public int add (Image image) { return index; } +private Image getOrClearIfDisposed(int index) { + if (images[index] != null && images[index].isDisposed()) { + images[index] = null; + } + return images[index]; +} + public int addRef() { return ++refCount; } @@ -337,7 +342,7 @@ public long getHandle(int targetZoom) { long newImageListHandle = OS.ImageList_Create(scaledWidth, scaledHeight, flags, 16, 16); int count = OS.ImageList_GetImageCount (handle); for (int i = 0; i < count; i++) { - Image image = images[i]; + Image image = getOrClearIfDisposed(i); if (image != null) { set(i, image, i, newImageListHandle, targetZoom); } else { @@ -372,9 +377,9 @@ public Point getImageSize() { public int indexOf (Image image) { int count = OS.ImageList_GetImageCount (handle); for (int i=0; i