aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2022-08-11 09:46:54 +0200
committerGitHub <noreply@github.com>2022-08-11 09:46:54 +0200
commit8be6039101a0c4006199c2946d8381c86428ec11 (patch)
treeb0e77ea39cf630bf84adb14eccd6cf50b2051371
parentebc0aa284e743869bdbfe97428d3aa320f1b7e09 (diff)
parent5d6df77291f0845e801b174f9f4d85c704b016c2 (diff)
Merge pull request #23627 from vespa-engine/mortent/path-validation
Path validation
-rw-r--r--vespajlib/src/main/java/ai/vespa/validation/PathValidator.java36
-rw-r--r--vespajlib/src/test/java/ai/vespa/validation/PathValidatorTest.java35
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());
+ }
+}