diff --git a/projects/core/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java b/projects/core/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java index 2ffc87391..2fa8a54b5 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java +++ b/projects/core/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java @@ -429,7 +429,9 @@ public static String sanitizePath(String path, boolean allowWildcards) { // Collapse the string into its component parts, removing ..'s var outputParts = new ArrayDeque(); - for (var part : Splitter.on('/').split(path)) { + for (var fullPart : Splitter.on('/').split(path)) { + var part = fullPart.strip(); + if (part.isEmpty() || part.equals(".") || threeDotsPattern.matcher(part).matches()) { // . is redundant // ... and more are treated as . @@ -450,7 +452,7 @@ public static String sanitizePath(String path, boolean allowWildcards) { } } else if (part.length() >= 255) { // If part length > 255 and it is the last part - outputParts.addLast(part.substring(0, 255)); + outputParts.addLast(part.substring(0, 255).strip()); } else { // Anything else we add to the stack outputParts.addLast(part); diff --git a/projects/core/src/test/java/dan200/computercraft/core/filesystem/FileSystemTest.java b/projects/core/src/test/java/dan200/computercraft/core/filesystem/FileSystemTest.java index b5c8b22fc..45636dc06 100644 --- a/projects/core/src/test/java/dan200/computercraft/core/filesystem/FileSystemTest.java +++ b/projects/core/src/test/java/dan200/computercraft/core/filesystem/FileSystemTest.java @@ -12,6 +12,8 @@ import dan200.computercraft.core.apis.ObjectWrapper; import dan200.computercraft.core.apis.handles.EncodedWritableHandle; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import java.io.File; import java.io.IOException; @@ -74,4 +76,21 @@ public void testUnmountCloses() throws FileSystemException { var err = assertThrows(LuaException.class, () -> wrapper.call("write", "Tiny line")); assertEquals("attempt to use a closed file", err.getMessage()); } + + @ParameterizedTest(name = "{0}") + @MethodSource("sanitiseCases") + public void testSanitize(String input, String output) { + assertEquals(output, FileSystem.sanitizePath(input, false)); + } + + public static String[][] sanitiseCases() { + return new String[][]{ + new String[]{ "a//b", "a/b" }, + new String[]{ "a/./b", "a/b" }, + new String[]{ "a/../b", "b" }, + new String[]{ "a/.../b", "a/b" }, + new String[]{ " a ", "a" }, + new String[]{ "a b c", "a b c" }, + }; + } }