Fix handling of file: module URIs with non-ASCII characters (#696)

Addresses an issue where Pkl cannot evaluate files with non-ASCII characters.
This commit is contained in:
Josh B
2024-10-23 20:52:40 -07:00
committed by GitHub
parent 5a654e453c
commit f9fe226eba
10 changed files with 121 additions and 9 deletions
@@ -18,7 +18,6 @@ package org.pkl.core;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.stream.StreamSupport;
import org.pkl.core.packages.PackageAssetUri;
import org.pkl.core.runtime.VmContext;
@@ -93,7 +92,7 @@ public final class StackFrameTransformers {
var uri = frame.getModuleUri();
if (!uri.startsWith("file:")) return frame;
return transformUri(frame, Path.of(URI.create(uri)).toString(), scheme);
return transformUri(frame, IoUtils.pathOf(URI.create(uri)).toString(), scheme);
};
}
@@ -24,12 +24,13 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.pkl.core.util.IoUtils;
public final class FileResolver {
private FileResolver() {}
public static List<PathElement> listElements(URI baseUri) throws IOException {
return listElements(Path.of(baseUri));
return listElements(IoUtils.pathOf(baseUri));
}
public static List<PathElement> listElements(Path path) throws IOException {
@@ -49,7 +50,7 @@ public final class FileResolver {
}
public static boolean hasElement(URI elementUri) {
return Files.exists(Path.of(elementUri));
return Files.exists(IoUtils.pathOf(elementUri));
}
public static boolean hasElement(Path path) {
@@ -16,7 +16,6 @@
package org.pkl.core.module;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -26,7 +25,6 @@ import java.net.URISyntaxException;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import org.pkl.core.SecurityManager;
@@ -325,7 +323,7 @@ public final class ModuleKeys {
if (java.io.File.separatorChar == '\\' && uriPath != null && uriPath.contains("\\")) {
throw new FileNotFoundException();
}
var realPath = Path.of(uri).toRealPath();
var realPath = IoUtils.pathOf(uri).toRealPath();
var resolvedUri = realPath.toUri();
securityManager.checkResolveModule(resolvedUri);
return ResolvedModuleKeys.file(this, resolvedUri, realPath);
@@ -88,6 +88,20 @@ public final class IoUtils {
return new URI(null, null, str, null);
}
/** Converts a URI to a Path, normalizing any non-ASCII characters. */
public static Path pathOf(URI uri) {
// Path.of(URI) throws on non-ASCII characters so the module URI here must be normalized to
// ASCII
// Unfortunately there's no way to go from URI -> ASCII URI directly
// so this must transform URI -> ASCII String -> ASCII URI
try {
return Path.of(new URI(uri.toASCIIString()));
} catch (URISyntaxException e) {
// impossible to get here; we started from a valid URI to begin with
throw PklBugException.unreachableCode();
}
}
/** Like {@link #toUri(String)}, except without checked exceptions. */
public static URI createUri(String str) {
try {