Correct --root-dir check to also work for jar:file: URIs (#1442)

This commit is contained in:
Jen Basch
2026-02-25 10:57:01 -08:00
committed by GitHub
parent be21c34938
commit 3ef065b6b6
2 changed files with 61 additions and 5 deletions

View File

@@ -24,6 +24,7 @@ import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import org.pkl.core.util.ErrorMessages;
import org.pkl.core.util.IoUtils;
import org.pkl.core.util.Nullable;
/** A provider for {@link SecurityManager}s. */
@@ -213,13 +214,17 @@ public final class SecurityManagers {
}
private void checkIsUnderRootDir(URI uri, boolean isResource) throws SecurityManagerException {
if (!uri.isAbsolute()) {
throw new AssertionError("Expected absolute URI but got: " + uri);
// handle jar:file: URIs correctly:
var checkUri =
uri.getScheme().equals("jar") ? IoUtils.createUri(uri.getSchemeSpecificPart()) : uri;
if (!checkUri.isAbsolute()) {
throw new AssertionError("Expected absolute URI but got: " + checkUri);
}
if (rootDir == null || !uri.getScheme().equals("file")) return;
if (rootDir == null || !checkUri.getScheme().equals("file")) return;
var path = Path.of(uri);
var path = Path.of(checkUri);
if (Files.exists(path)) {
try {
path = path.toRealPath();

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -283,6 +283,57 @@ class EvaluatorTest {
)
}
@Test
fun `cannot import module from zip filesystem located outside root dir`(
@TempDir tempDir: Path,
@TempDir forbidden: Path,
) {
val evaluator =
with(EvaluatorBuilder.preconfigured()) {
rootDir = tempDir
build()
}
val zipFile = createModulesZip(forbidden)
val module =
tempDir
.resolve("test.pkl")
.writeString("res = import(\"jar:${zipFile.toUri()}!/foo/var/module1.pkl\")")
val e = assertThrows<PklException> { evaluator.evaluate(path(module)) }
assertThat(e)
.hasMessageContaining(
"Refusing to load module `jar:${zipFile.toUri()}!/foo/var/module1.pkl` because it is not within the root directory (`--root-dir`)."
)
}
@Test
fun `cannot read resource from zip filesystem located outside root dir`(
@TempDir tempDir: Path,
@TempDir forbidden: Path,
) {
val evaluator =
with(EvaluatorBuilder.preconfigured()) {
rootDir = tempDir
allowedResources.add(Pattern.compile("jar:file:"))
build()
}
val zipFile = createModulesZip(forbidden)
val module =
tempDir
.resolve("test.pkl")
.writeString("res = read(\"jar:${zipFile.toUri()}!/foo/var/module1.pkl\")")
val e = assertThrows<PklException> { evaluator.evaluate(path(module)) }
assertThat(e)
.hasMessageContaining(
"Refusing to read resource `jar:${zipFile.toUri()}!/foo/var/module1.pkl` because it is not within the root directory (`--root-dir`)."
)
}
@Test
fun `cannot read resource located outside root dir`(@TempDir tempDir: Path) {
val evaluator =