diff options
3 files changed, 80 insertions, 9 deletions
diff --git a/jimfs/src/main/java/com/google/jimfs/internal/FileTree.java b/jimfs/src/main/java/com/google/jimfs/internal/FileTree.java index 044cbcf..d3eaa55 100644 --- a/jimfs/src/main/java/com/google/jimfs/internal/FileTree.java +++ b/jimfs/src/main/java/com/google/jimfs/internal/FileTree.java @@ -98,10 +98,9 @@ final class FileTree { // lookup the root directory DirectoryEntry entry = superRoot.asDirectoryTable().get(path.root()); if (entry == null) { - // root not found - return !names.isEmpty() - ? null - : new DirectoryEntry(superRoot, path.root(), null); + // root not found; always return null as no real parent directory exists + // this prevents new roots from being created in file systems supporting multiple roots + return null; } else if (names.isEmpty()) { // root found, no more names to look up return entry; diff --git a/jimfs/src/test/java/com/google/jimfs/JimfsWindowsLikeIntegrationTest.java b/jimfs/src/test/java/com/google/jimfs/JimfsWindowsLikeIntegrationTest.java index e09e641..362e873 100644 --- a/jimfs/src/test/java/com/google/jimfs/JimfsWindowsLikeIntegrationTest.java +++ b/jimfs/src/test/java/com/google/jimfs/JimfsWindowsLikeIntegrationTest.java @@ -274,4 +274,61 @@ public class JimfsWindowsLikeIntegrationTest extends AbstractJimfsIntegrationTes } catch (UnsupportedOperationException expected) { } } + + @Test + public void testCreateFileOrDirectory_forRootPath_fails() throws IOException { + try { + Files.createDirectory(path("Z:\\")); + fail(); + } catch (IOException expected) { + } + + try { + Files.createFile(path("Z:\\")); + fail(); + } catch (IOException expected) { + } + + try { + Files.createSymbolicLink(path("Z:\\"), path("foo")); + fail(); + } catch (IOException expected) { + } + } + + @Test + public void testCopyFile_toRootPath_fails() throws IOException { + Files.createFile(path("foo")); + Files.createDirectory(path("bar")); + + try { + Files.copy(path("foo"), path("Z:\\")); + fail(); + } catch (IOException expected) { + } + + try { + Files.copy(path("bar"), path("Z:\\")); + fail(); + } catch (IOException expected) { + } + } + + @Test + public void testMoveFile_toRootPath_fails() throws IOException { + Files.createFile(path("foo")); + Files.createDirectory(path("bar")); + + try { + Files.move(path("foo"), path("Z:\\")); + fail(); + } catch (IOException expected) { + } + + try { + Files.move(path("bar"), path("Z:\\")); + fail(); + } catch (IOException expected) { + } + } } diff --git a/jimfs/src/test/java/com/google/jimfs/internal/FileTreeTest.java b/jimfs/src/test/java/com/google/jimfs/internal/FileTreeTest.java index e390021..4e66e7d 100644 --- a/jimfs/src/test/java/com/google/jimfs/internal/FileTreeTest.java +++ b/jimfs/src/test/java/com/google/jimfs/internal/FileTreeTest.java @@ -69,8 +69,8 @@ public class FileTreeTest { */ /** - * This path service is for unix-like paths, with the exception that it recognizes $ as a root in - * addition to /, allowing for two roots. + * This path service is for unix-like paths, with the exception that it recognizes $ and ! as + * roots in addition to /, allowing for up to three roots. */ private final PathService pathService = fakePathService( new PathType(CaseSensitivity.CASE_SENSITIVE, true, '/') { @@ -82,7 +82,7 @@ public class FileTreeTest { @Override public ParseResult parsePath(String path) { String root = null; - if (path.startsWith("/") || path.startsWith("$")) { + if (path.matches("^[/$!].*")) { root = path.substring(0, 1); path = path.substring(1); } @@ -103,8 +103,8 @@ public class FileTreeTest { @Override public ParseResult parseUriPath(String uriPath) { - checkArgument(uriPath.startsWith("//") || uriPath.startsWith("/$"), - "uriPath (%s) must start with // or /$"); + checkArgument(uriPath.matches("^/[/$!].*"), + "uriPath (%s) must start with // or /$ or /!"); return parsePath(uriPath.substring(1)); // skip leading / } }); @@ -163,6 +163,21 @@ public class FileTreeTest { } @Test + public void testLookup_nonExistentRoot() throws IOException { + try { + lookup("!"); + fail(); + } catch (NoSuchFileException expected) { + } + + try { + lookup("!a"); + fail(); + } catch (NoSuchFileException expected) { + } + } + + @Test public void testLookup_absolute() throws IOException { assertExists(lookup("/work"), "/", "work"); assertExists(lookup("/work/one/two/three"), "two", "three"); |