Skip to content

Commit

Permalink
Add existence check (file protocol) in URLImageDescriptor.getFilePath()
Browse files Browse the repository at this point in the history
The URLImageDescriptor.getFilePath() method currently returns a path for
a given URL using the file protocol even if the file does not exist.
This conflicts with the method's contract and breaks consumers (such as
the scaled image data retrieval in SWT's DPIUtil).

With this change, the method properly checks for the existence of a file
at the given location and returns null in case it does not exist,
according to the method's contract. A test case is added to demonstrate
the bug and detect regressions.
  • Loading branch information
HeikoKlare committed Apr 3, 2024
1 parent 3f00c8b commit cff785d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IAdaptable;
Expand Down Expand Up @@ -267,8 +269,12 @@ private static String getFilePath(URL url, boolean logIOException) {
url = platformURL;
}
URL locatedURL = FileLocator.toFileURL(url);
if (FILE_PROTOCOL.equalsIgnoreCase(locatedURL.getProtocol()))
return IPath.fromOSString(locatedURL.getPath()).toOSString();
if (FILE_PROTOCOL.equalsIgnoreCase(locatedURL.getProtocol())) {
String filePath = IPath.fromOSString(locatedURL.getPath()).toOSString();
if (Files.exists(Path.of(filePath))) {
return filePath;
}
}
return null;
} catch (IOException e) {
if (logIOException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;

import java.io.IOException;
import java.net.URL;

import org.eclipse.core.runtime.Adapters;
Expand All @@ -29,10 +30,15 @@
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageFileNameProvider;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class UrlImageDescriptorTest {

@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();

/**
* Test that individually created images of a given descriptor are not equal
* (See issue #682).
Expand Down Expand Up @@ -114,6 +120,24 @@ public void testImageFileNameProviderGetxName() {
assertNull("URLImageDescriptor's ImageFileNameProvider does return a @1.5x path", imagePath150);
}

@Test
public void testImageFileNameProviderGetxName_forFileURL() throws IOException {
URL imageFileURL = tempFolder.newFile("image.png").toURI().toURL();
tempFolder.newFile("image@2x.png");
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);
assertEquals(IPath.fromOSString(imagePath100).lastSegment(), "image.png");
String imagePath200 = fileNameProvider.getImagePath(200);
assertNotNull("URLImageDescriptor ImageFileNameProvider does not return the @2x path", imagePath200);
assertEquals(IPath.fromOSString(imagePath200).lastSegment(), "image@2x.png");
String imagePath150 = fileNameProvider.getImagePath(150);
assertNull("URLImageDescriptor's ImageFileNameProvider does return a @1.5x path", imagePath150);
}

@Test
public void testAdaptToURL() {
ImageDescriptor descriptor = ImageDescriptor
Expand Down

0 comments on commit cff785d

Please sign in to comment.