From 5058445ef67b89f83a2025db4dfcf1bbcc8115c6 Mon Sep 17 00:00:00 2001 From: Patrick Ziegler Date: Mon, 26 Jan 2026 19:42:04 +0100 Subject: [PATCH] Fix improper ImageData size when loading SVG from InputStream #3011 On Linux and MacOS, loading an `Image` from an `InputStream` is internally handled via an `ImageDataAtSizeProvider`. When loading `ImageData` by zoom, this interface requires a proper implementation of the `getDefaultSize()` or `getImageData(int)` method. Otherwise an `ImageData` of size 1x1 is returned at 100% zoom, otherwise `null`. The tests have been updated to test the loading of an `Image` from an `InputStream` and to also check the size of the `ImageData` at 100% zoom. Closes https://github.com/eclipse-platform/eclipse.platform.swt/issues/3011 --- .../cocoa/org/eclipse/swt/graphics/Image.java | 17 +++++++++-- .../gtk/org/eclipse/swt/graphics/Image.java | 17 +++++++++-- ...rg_eclipse_swt_internal_SVGRasterizer.java | 29 ++++++++++++++++++- 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java index f87d2c3a960..efc5d4f3b1b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2025 IBM Corporation and others. + * Copyright (c) 2000, 2026 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -1520,8 +1520,19 @@ private void initUsingImageDataProvider(ImageDataProvider imageDataProvider) { private static ImageDataProvider createImageDataProvider(InputStream stream) throws IOException { byte[] streamData = stream.readAllBytes(); if (ImageDataLoader.isDynamicallySizable(new ByteArrayInputStream(streamData))) { - ImageDataAtSizeProvider imageDataAtSizeProvider = (width, height) -> ImageDataLoader - .loadBySize(new ByteArrayInputStream(streamData), width, height); + ImageDataAtSizeProvider imageDataAtSizeProvider = new ImageDataAtSizeProvider() { + @Override + public ImageData getImageData(int zoom) { + return ImageDataLoader + .loadByZoom(new ByteArrayInputStream(streamData), FileFormat.DEFAULT_ZOOM, zoom) + .element(); + } + + @Override + public ImageData getImageData(int width, int height) { + return ImageDataLoader.loadBySize(new ByteArrayInputStream(streamData), width, height); + } + }; return imageDataAtSizeProvider; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java index 8f6cf9ec333..8e08a3cd97c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2025 IBM Corporation and others. + * Copyright (c) 2000, 2026 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -811,8 +811,19 @@ private void initFromImageDataProvider(int zoom) { private static ImageDataProvider createImageDataProvider(InputStream stream) throws IOException { byte[] streamData = stream.readAllBytes(); if (ImageDataLoader.isDynamicallySizable(new ByteArrayInputStream(streamData))) { - ImageDataAtSizeProvider imageDataAtSizeProvider = (width, height) -> ImageDataLoader - .loadBySize(new ByteArrayInputStream(streamData), width, height); + ImageDataAtSizeProvider imageDataAtSizeProvider = new ImageDataAtSizeProvider() { + @Override + public ImageData getImageData(int zoom) { + return ImageDataLoader + .loadByZoom(new ByteArrayInputStream(streamData), FileFormat.DEFAULT_ZOOM, zoom) + .element(); + } + + @Override + public ImageData getImageData(int width, int height) { + return ImageDataLoader.loadBySize(new ByteArrayInputStream(streamData), width, height); + } + }; return imageDataAtSizeProvider; } diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_internal_SVGRasterizer.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_internal_SVGRasterizer.java index 3f4c582f880..5fd390f4216 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_internal_SVGRasterizer.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_internal_SVGRasterizer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025 Vector Informatik GmbH and others. + * Copyright (c) 2025, 2026 Vector Informatik GmbH and others. * * This program and the accompanying materials are made available under the terms of the Eclipse * Public License 2.0 which accompanies this distribution, and is available at @@ -13,8 +13,11 @@ package org.eclipse.swt.tests.junit; import static org.eclipse.swt.tests.junit.SwtTestUtil.assertSWTProblem; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Path; import org.eclipse.swt.SWT; @@ -42,10 +45,31 @@ private static String getPath(String fileName) { return SwtTestUtil.getPath(fileName, tempFolder).toString(); } + @Test + public void test_ConstructorLorg_eclipse_swt_graphics_Device_InputStream() throws IOException { + Image image = null; + try (InputStream is = getClass().getResourceAsStream("collapseall.svg")) { + image = new Image(Display.getDefault(), is); + } + ImageData imageData = image.getImageData(); + assertEquals(16, imageData.width); + assertEquals(16, imageData.height); + image.dispose(); + + try (InputStream is = getClass().getResourceAsStream("corrupt.svg")) { + SWTException e = assertThrows(SWTException.class, + () -> new Image(Display.getDefault(), is)); + assertSWTProblem("Incorrect exception thrown for provider with corrupt images", SWT.ERROR_INVALID_IMAGE, e); + } + } + @Test public void test_ConstructorLorg_eclipse_swt_graphics_Device_ImageFileNameProvider() { ImageFileNameProvider validImageFileNameProvider = zoom -> getPath("collapseall.svg"); Image image = new Image(Display.getDefault(), validImageFileNameProvider); + ImageData imageData = image.getImageData(); + assertEquals(16, imageData.width); + assertEquals(16, imageData.height); image.dispose(); ImageFileNameProvider corruptImageFileNameProvider = zoom -> getPath("corrupt.svg"); @@ -58,6 +82,9 @@ public void test_ConstructorLorg_eclipse_swt_graphics_Device_ImageFileNameProvid public void test_ConstructorLorg_eclipse_swt_graphics_Device_ImageDataProvider() { ImageDataProvider validImageDataProvider = zoom -> (zoom == 100) ? new ImageData(getPath("collapseall.svg")) : null; Image image = new Image(Display.getDefault(), validImageDataProvider); + ImageData imageData = image.getImageData(); + assertEquals(16, imageData.width); + assertEquals(16, imageData.height); image.dispose(); ImageDataProvider corruptImageDataProvider = zoom -> (zoom == 100) ? new ImageData(getPath("corrupt.svg")) : null;