Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion substratevm/mx.substratevm/suite.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# pylint: disable=line-too-long
suite = {
"mxversion": "5.316.15",
"mxversion": "5.319.0",
"name": "substratevm",
"version" : "22.1.0",
"release" : False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
Expand All @@ -43,7 +42,6 @@
import org.graalvm.nativeimage.hosted.Feature;

import com.oracle.svm.core.annotate.AutomaticFeature;
import com.oracle.svm.core.jdk.resources.NativeImageResourcePath;
import com.oracle.svm.core.jdk.resources.ResourceStorageEntry;
import com.oracle.svm.core.util.ImageHeapMap;
import com.oracle.svm.core.util.VMError;
Expand Down Expand Up @@ -85,9 +83,13 @@ public static byte[] inputStreamToByteArray(InputStream is) {
}
}

private static String getResourceWithoutTrailingSlash(String name) {
return name.endsWith("/") ? name.substring(0, name.length() - 1) : name;
}

private static void addEntry(String moduleName, String resourceName, boolean isDirectory, byte[] data) {
Resources support = singleton();
Pair<String, String> key = Pair.create(moduleName, resourceName);
Pair<String, String> key = Pair.create(moduleName, getResourceWithoutTrailingSlash(resourceName));
ResourceStorageEntry entry = support.resources.get(key);
if (entry == null) {
entry = new ResourceStorageEntry(isDirectory);
Expand Down Expand Up @@ -121,21 +123,17 @@ public static void registerDirectoryResource(String moduleName, String resourceD
addEntry(moduleName, resourceDirName, true, content.getBytes());
}

/**
* Avoid pulling native file system by using {@link NativeImageResourcePath} implementation to
* convert <code>resourceName</code> to canonical variant.
*/
public static String toCanonicalForm(String resourceName) {
NativeImageResourcePath path = new NativeImageResourcePath(null, resourceName.getBytes(StandardCharsets.UTF_8), true);
return new String(NativeImageResourcePath.getResolved(path));
}

public static ResourceStorageEntry get(String name) {
return singleton().resources.get(Pair.createRight(name));
return get(null, name);
}

public static ResourceStorageEntry get(String moduleName, String resourceName) {
return singleton().resources.get(Pair.create(moduleName, resourceName));
ResourceStorageEntry resourceStorageEntry = singleton().resources.get(Pair.create(moduleName, getResourceWithoutTrailingSlash(resourceName)));
if (resourceStorageEntry != null && (resourceStorageEntry.isDirectory() || !resourceName.endsWith("/"))) {
return resourceStorageEntry;
} else {
return null;
}
}

private static URL createURL(String moduleName, String resourceName, int index) {
Expand All @@ -156,7 +154,7 @@ public static URL createURL(String moduleName, String resourceName) {
return null;
}

Enumeration<URL> urls = createURLs(moduleName, toCanonicalForm(resourceName));
Enumeration<URL> urls = createURLs(moduleName, resourceName);
return urls.hasMoreElements() ? urls.nextElement() : null;
}

Expand All @@ -170,7 +168,7 @@ public static InputStream createInputStream(String moduleName, String resourceNa
return null;
}

ResourceStorageEntry entry = Resources.get(moduleName, toCanonicalForm(resourceName));
ResourceStorageEntry entry = Resources.get(moduleName, resourceName);
if (entry == null) {
return null;
}
Expand All @@ -186,33 +184,32 @@ public static Enumeration<URL> createURLs(String moduleName, String resourceName
if (resourceName == null) {
return null;
}
String canonicalResourceName = toCanonicalForm(resourceName);

List<URL> resourcesURLs = new ArrayList<>();

/* If moduleName was unspecified we have to consider all modules in the image */
if (moduleName == null) {
for (Module module : BootModuleLayerSupport.instance().getBootLayer().modules()) {
ResourceStorageEntry entry = Resources.get(module.getName(), canonicalResourceName);
addURLEntries(resourcesURLs, entry, module.getName(), canonicalResourceName);
ResourceStorageEntry entry = Resources.get(module.getName(), resourceName);
addURLEntries(resourcesURLs, entry, module.getName(), resourceName);
}
}
ResourceStorageEntry explicitEntry = Resources.get(moduleName, canonicalResourceName);
addURLEntries(resourcesURLs, explicitEntry, moduleName, canonicalResourceName);
ResourceStorageEntry explicitEntry = Resources.get(moduleName, resourceName);
addURLEntries(resourcesURLs, explicitEntry, moduleName, resourceName);

if (resourcesURLs.isEmpty()) {
return Collections.emptyEnumeration();
}
return Collections.enumeration(resourcesURLs);
}

private static void addURLEntries(List<URL> resourcesURLs, ResourceStorageEntry entry, String moduleName, String canonicalResourceName) {
private static void addURLEntries(List<URL> resourcesURLs, ResourceStorageEntry entry, String moduleName, String resourceName) {
if (entry == null) {
return;
}
int numberOfResources = entry.getData().size();
for (int index = 0; index < numberOfResources; index++) {
resourcesURLs.add(createURL(moduleName, canonicalResourceName, index));
resourcesURLs.add(createURL(moduleName, resourceName, index));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void connect() {
throw new IllegalArgumentException("Empty URL path not allowed in " + JavaNetSubstitutions.RESOURCE_PROTOCOL + " URL");
}
String resourceName = urlPath.substring(1);
ResourceStorageEntry entry = Resources.get(hostNameOrNull, Resources.toCanonicalForm(resourceName));
ResourceStorageEntry entry = Resources.get(hostNameOrNull, resourceName);
if (entry != null) {
List<byte[]> bytes = entry.getData();
String urlRef = url.getRef();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
// Remove leading / for the resource patterns
registry.addResources(ConfigurationCondition.alwaysTrue(), RESOURCE_FILE_1.substring(1));
registry.addResources(ConfigurationCondition.alwaysTrue(), RESOURCE_FILE_2.substring(1));
registry.addResources(ConfigurationCondition.alwaysTrue(), RESOURCE_DIR.substring(1));

/** Needed for {@link #testURLExternalFormEquivalence()} */
for (Module module : ModuleLayer.boot().modules()) {
Expand Down Expand Up @@ -631,4 +632,22 @@ public void testURLExternalFormEquivalence() {
Assert.fail("Contents of original URL and one created from originals ExternalForm must be the same: " + e);
}
}

@Test
public void noCanonicalizationInGetResource() {
Class<?> klass = NativeImageResourceFileSystemProviderTest.class;
URL url = klass.getResource(RESOURCE_DIR + "/");
Assert.assertNotNull(url);
Assert.assertTrue(url.toString().endsWith("/"));
url = klass.getResource(RESOURCE_DIR);
Assert.assertNotNull(url);
Assert.assertFalse(url.toString().endsWith("/"));
url = klass.getResource(RESOURCE_DIR + "/./");
Assert.assertNull(url);
url = klass.getResource(RESOURCE_FILE_1);
Assert.assertNotNull(url);
url = klass.getResource(RESOURCE_FILE_1 + "/");
Assert.assertNull(url);
}

}
1 change: 1 addition & 0 deletions substratevm/src/com.oracle.svm.test/src/resources/.mxkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file instructs mx to create a jar entry for the parent directory