diff options
author | Harald Musum <musum@verizonmedia.com> | 2022-08-11 09:46:54 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-11 09:46:54 +0200 |
commit | 8be6039101a0c4006199c2946d8381c86428ec11 (patch) | |
tree | b0e77ea39cf630bf84adb14eccd6cf50b2051371 | |
parent | ebc0aa284e743869bdbfe97428d3aa320f1b7e09 (diff) | |
parent | 5d6df77291f0845e801b174f9f4d85c704b016c2 (diff) |
Merge pull request #23627 from vespa-engine/mortent/path-validation
Path validation
-rw-r--r-- | vespajlib/src/main/java/ai/vespa/validation/PathValidator.java | 36 | ||||
-rw-r--r-- | vespajlib/src/test/java/ai/vespa/validation/PathValidatorTest.java | 35 |
2 files changed, 71 insertions, 0 deletions
diff --git a/vespajlib/src/main/java/ai/vespa/validation/PathValidator.java b/vespajlib/src/main/java/ai/vespa/validation/PathValidator.java new file mode 100644 index 00000000000..0ae81e2315d --- /dev/null +++ b/vespajlib/src/main/java/ai/vespa/validation/PathValidator.java @@ -0,0 +1,36 @@ +package ai.vespa.validation; + +import java.nio.file.Path; + +/** + * Path validations + * + * @author mortent + */ +public class PathValidator { + + /** + * Validate that file is a child of basedir + * @param root Root directory to use for validation + * @param path Path to validate + * @throws IllegalArgumentException if path is not a child of root + */ + public static void validateChildOf(Path root, Path path) { + if (!path.normalize().startsWith(root)) { + throw new IllegalArgumentException("Invalid path %s".formatted(path)); + } + } + + /** + * Resolves a path under a root path + * @param root root poth + * @param path child to resolve + * @return The resolved path + * @throws IllegalArgumentException If the provided child path does not resolve as child of root + */ + public static Path resolveChildOf(Path root, String path) { + Path resolved = root.resolve(path); + validateChildOf(root, resolved); + return resolved; + } +} diff --git a/vespajlib/src/test/java/ai/vespa/validation/PathValidatorTest.java b/vespajlib/src/test/java/ai/vespa/validation/PathValidatorTest.java new file mode 100644 index 00000000000..a2c1bd6bd0c --- /dev/null +++ b/vespajlib/src/test/java/ai/vespa/validation/PathValidatorTest.java @@ -0,0 +1,35 @@ +package ai.vespa.validation; + +import org.junit.Test; + +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class PathValidatorTest { + + @Test + public void testPathValidation() { + Path root = Path.of("/foo/"); + + assertOk(Path.of("/foo/bar"), root); + assertOk(Path.of("/foo/foo2/bar"), root); + assertOk(Path.of("/foo/foo2/../bar"), root); + assertOk(Path.of("/foo/../foo/bar"), root); + assertOk(Path.of("/bar/../foo/../foo/bar"), root); + + assertInvalid(Path.of("/foo/../bar"), root); + assertInvalid(Path.of("/foo/bar/../../bar"), root); + } + + private void assertOk(Path path, Path root) { + PathValidator.validateChildOf(root, path); + } + + private void assertInvalid(Path path, Path root) { + IllegalArgumentException illegalArgumentException = assertThrows(IllegalArgumentException.class, + () -> PathValidator.validateChildOf(root, path)); + assertEquals("Invalid path %s".formatted(path), illegalArgumentException.getMessage()); + } +} |