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
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,22 @@
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import com.oracle.svm.core.jdk.resources.ResourceStorageEntry;
import com.oracle.svm.core.jdk.resources.ResourceURLConnection;
import org.graalvm.collections.EconomicMap;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
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.jdk.resources.ResourceURLConnection;
import com.oracle.svm.core.util.ImageHeapMap;
import com.oracle.svm.core.util.VMError;

Expand All @@ -57,6 +59,8 @@
*/
public final class Resources {

public static final char RESOURCES_INTERNAL_PATH_SEPARATOR = '/';

public static Resources singleton() {
return ImageSingletons.lookup(Resources.class);
}
Expand Down Expand Up @@ -121,6 +125,15 @@ public static void registerDirectoryResource(String resourceDirName, String cont
addEntry(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(name);
}
Expand All @@ -144,7 +157,8 @@ public static URL createURL(String resourceName) {
if (resourceName == null) {
return null;
}
Enumeration<URL> urls = createURLs(resourceName);

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

Expand All @@ -153,7 +167,8 @@ public static InputStream createInputStream(String resourceName) {
if (resourceName == null) {
return null;
}
ResourceStorageEntry entry = Resources.get(resourceName);

ResourceStorageEntry entry = Resources.get(toCanonicalForm(resourceName));
if (entry == null) {
return null;
}
Expand All @@ -165,14 +180,16 @@ public static Enumeration<URL> createURLs(String resourceName) {
if (resourceName == null) {
return null;
}
ResourceStorageEntry entry = Resources.get(resourceName);

String canonicalResourceName = toCanonicalForm(resourceName);
ResourceStorageEntry entry = Resources.get(canonicalResourceName);
if (entry == null) {
return Collections.emptyEnumeration();
}
int numberOfResources = entry.getData().size();
List<URL> resourcesURLs = new ArrayList<>(numberOfResources);
for (int index = 0; index < numberOfResources; index++) {
resourcesURLs.add(createURL(resourceName, index));
resourcesURLs.add(createURL(canonicalResourceName, index));
}
return Collections.enumeration(resourcesURLs);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -603,13 +603,13 @@ private byte[] getResolved() {
}
for (byte c : path) {
if (c == '.') {
return doGetResolved(this);
return getResolved(this);
}
}
return path;
}

private static byte[] doGetResolved(NativeImageResourcePath p) {
public static byte[] getResolved(NativeImageResourcePath p) {
int nc = p.getNameCount();
byte[] path = p.path;
int[] offsets = p.offsets;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void connect() {
connected = true;

String resourceName = resolveName(url.getPath());
ResourceStorageEntry entry = Resources.get(resourceName);
ResourceStorageEntry entry = Resources.get(Resources.toCanonicalForm(resourceName));
if (entry != null) {
List<byte[]> bytes = entry.getData();
if (index < bytes.size()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

package com.oracle.svm.hosted;

import static com.oracle.svm.core.jdk.Resources.RESOURCES_INTERNAL_PATH_SEPARATOR;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
Expand All @@ -48,6 +50,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.oracle.svm.core.util.VMError;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionType;
Expand Down Expand Up @@ -268,7 +271,7 @@ private static void scanDirectory(DebugContext debugContext, Path root, Pattern[
/* Resources always use / as the separator, as do our resource inclusion patterns */
String relativeFilePath;
if (entry != root) {
relativeFilePath = root.relativize(entry).toString().replace(File.separatorChar, '/');
relativeFilePath = root.relativize(entry).toString().replace(File.separatorChar, RESOURCES_INTERNAL_PATH_SEPARATOR);
allEntries.add(relativeFilePath);
} else {
relativeFilePath = "";
Expand All @@ -291,7 +294,7 @@ private static void scanDirectory(DebugContext debugContext, Path root, Pattern[
}

for (String entry : allEntries) {
int last = entry.lastIndexOf('/');
int last = entry.lastIndexOf(RESOURCES_INTERNAL_PATH_SEPARATOR);
String key = last == -1 ? "" : entry.substring(0, last);
List<String> dirContent = matchedDirectoryResources.get(key);
if (dirContent != null && !dirContent.contains(entry)) {
Expand Down Expand Up @@ -328,14 +331,16 @@ private static void scanJar(DebugContext debugContext, Path jarPath, Pattern[] i
}

private static boolean matches(Pattern[] includePatterns, Pattern[] excludePatterns, String relativePath) {
VMError.guarantee(!relativePath.contains("\\"), "Resource path contains backslash!");
String relativePathWithTrailingSlash = relativePath + RESOURCES_INTERNAL_PATH_SEPARATOR;
for (Pattern p : excludePatterns) {
if (p.matcher(relativePath).matches()) {
if (p.matcher(relativePath).matches() || p.matcher(relativePathWithTrailingSlash).matches()) {
return false;
}
}

for (Pattern p : includePatterns) {
if (p.matcher(relativePath).matches()) {
if (p.matcher(relativePath).matches() || p.matcher(relativePathWithTrailingSlash).matches()) {
return true;
}
}
Expand Down