From 33616c6cc60eb9ed101338c0c256d8a3980fa570 Mon Sep 17 00:00:00 2001 From: "Patrick.Ziegler" Date: Thu, 17 Jul 2025 14:11:00 +0200 Subject: [PATCH] Restore correct URL/URI handling in URLImageDescriptor The changes done with cee46311e84ba41e8a421b47099ad709e23761f1 cause an exception when an URL is passed as argument, which contains improperly escaped characters (most noticeably whitespaces) and therefore causes an URISyntaxException when calling URL.toURI(). This does not occur when using IPath.fromOSString(), which is the approach that was done previously. But instead of converting this path back to an OS-dependent string, it is instead converted to a file, to check whether it exists and to only then convert it back to its String representation. A test case with an ill-formed URL has been added to avoid a similar problem in the future. --- .../jface/resource/URLImageDescriptor.java | 15 +++++++-------- .../tests/images/UrlImageDescriptorTest.java | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java index d57d14844a1..646ca5cb90f 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java @@ -19,19 +19,18 @@ import java.io.BufferedInputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; -import java.net.URISyntaxException; import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Status; import org.eclipse.jface.internal.InternalPolicy; import org.eclipse.jface.util.Policy; @@ -254,7 +253,7 @@ private static String getFilePath(URL url, boolean logException) { url = resolvePathVariables(url); URL locatedURL = FileLocator.toFileURL(url); return getFilePath(locatedURL); - } catch (IOException | URISyntaxException e) { + } catch (IOException e) { if (logException) { Policy.logException(e); } else if (InternalPolicy.DEBUG_LOG_URL_IMAGE_DESCRIPTOR_MISSING_2x) { @@ -267,11 +266,11 @@ private static String getFilePath(URL url, boolean logException) { } } - private static String getFilePath(URL url) throws URISyntaxException { + private static String getFilePath(URL url) { if (FILE_PROTOCOL.equalsIgnoreCase(url.getProtocol())) { - Path filePath = Path.of(url.toURI()); - if (Files.exists(filePath)) { - return filePath.toString(); + File file = IPath.fromOSString(url.getPath()).toFile(); + if (file.exists()) { + return file.getPath(); } } return null; diff --git a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/images/UrlImageDescriptorTest.java b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/images/UrlImageDescriptorTest.java index 1e6cfb8a437..ead4939cca0 100644 --- a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/images/UrlImageDescriptorTest.java +++ b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/images/UrlImageDescriptorTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; +import java.io.File; import java.io.IOException; import java.net.URL; @@ -154,6 +155,23 @@ private void testImageFileNameProviderGetxName_forFileURL(boolean osgiAvailable) } } + @Test + public void testImageFileNameProviderGetxName_forFileURL_WhiteSpace() throws IOException { + File imageFolder = tempFolder.newFolder("folder with spaces"); + File imageFile = new File(imageFolder, "image with spaces.png"); + imageFile.createNewFile(); + + // This is an invalid URL because the whitespace characters are not properly encoded + URL imageFileURL = new URL("file", null, imageFile.getPath()); + ImageDescriptor descriptor = ImageDescriptor.createFromURL(imageFileURL); + + ImageFileNameProvider fileNameProvider = Adapters.adapt(descriptor, ImageFileNameProvider.class); + assertNotNull("URLImageDescriptor does not adapt to ImageFileNameProvider", fileNameProvider); + + String imagePath100 = fileNameProvider.getImagePath(100); + assertNotNull("URLImageDescriptor ImageFileNameProvider does not return the 100% path", imagePath100); + } + @Test public void testAdaptToURL() { ImageDescriptor descriptor = ImageDescriptor