Repository navigation
Cross file-system path handling #8227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
98ac830
ca91b5a
39af575
cdf39eb
5f21296
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,9 @@ | |
| <%@ page import="org.junit.Before" %> | ||
| <%@ page import="org.junit.Test" %> | ||
| <%@ page import="java.io.File" %> | ||
| <%@ page import="java.io.IOException" %> | ||
| <%@ page import="java.io.FileNotFoundException" %> | ||
| <%@ page import="java.nio.file.Files" %> | ||
| <%@ page import="java.net.URI" %> | ||
| <%@ page import="org.labkey.api.util.FileUtil" %> | ||
| <%@ page import="org.labkey.vfs.FileSystemLike" %> | ||
|
|
@@ -69,14 +72,20 @@ | |
|
|
||
| FileLike tempDir = new FileSystemLike.Builder(tempPath.toFile()).root(); | ||
| assertNotNull(tempDir); | ||
| FileLike t1 = tempDir.resolveFile(Path.parse(tempPath + "\\b\\t1.txt")); | ||
| FileLike t1 = tempDir.resolveFile(Path.parse("b/t1.txt")); | ||
| assertNotNull(t1); | ||
| FileLike td1 = tempDir.resolveFile(Path.parse(tempPath + "\\b\\")); | ||
| FileLike td1 = tempDir.resolveFile(Path.parse("b/")); | ||
| assertNotNull(td1); | ||
| FileLike tc1 = td1.resolveChild("t1.txt"); | ||
| assertNotNull(tc1); | ||
| assertEquals(t1, tc1); | ||
|
|
||
| for (String name : new String[] {tempPath + "\\b\\t1.txt", "..\\x", "a\\..\\..\\x", "a\\b", "C:\\x", "C:x", "\\x", "\\\\host\\share\\x", "a<b.txt", "a|b"}) | ||
| { | ||
| assertThrows(name, FileUtil.InvalidPathReferenceException.class, () -> tempDir.resolveFile(new Path(name))); | ||
| assertThrows(name, FileUtil.InvalidPathReferenceException.class, () -> tempDir.resolveChild(name)); | ||
| } | ||
|
|
||
| FileLike root = new FileSystemLike.Builder(new File("C:\\")).root(); | ||
| assertNotNull(root); | ||
| FileLike r1 = root.resolveFile(Path.parse("r1.txt")); | ||
|
|
@@ -203,9 +212,65 @@ | |
| } | ||
|
|
||
|
|
||
| void resolve(FileSystemLike fs) | ||
| @Test | ||
| public void testWrapFile() throws Exception | ||
| { | ||
| File root = tempPath.toFile(); | ||
| java.nio.file.Path nested = Files.createFile(Files.createDirectory(tempPath.resolve("sub")).resolve("f.txt")); | ||
|
|
||
| FileLike fromFile = FileSystemLike.wrapFile(root, nested.toFile()); | ||
| assertEquals(2, fromFile.getPath().size()); | ||
| assertEquals("sub", fromFile.getPath().get(0)); | ||
| assertEquals("f.txt", fromFile.getName()); | ||
| assertTrue(fromFile.isFile()); | ||
|
|
||
| FileLike fromNio = FileSystemLike.wrapFile(tempPath, nested); | ||
| assertEquals(fromFile, fromNio); | ||
| assertTrue(fromNio.isFile()); | ||
|
|
||
| assertThrows(IOException.class, () -> FileSystemLike.wrapFile(root, new File(root.getParentFile(), "x.txt"))); | ||
| assertThrows(IOException.class, () -> FileSystemLike.wrapFile(root, new File(new File(root.getParentFile(), root.getName() + "foo"), "x.txt"))); | ||
| assertThrows(IOException.class, () -> FileSystemLike.wrapFile(root, new File(root, "sub/../../x.txt"))); | ||
| assertEquals(fromFile, FileSystemLike.wrapFile(root, new File(root, "sub/../sub/f.txt"))); | ||
|
|
||
| FileLike self = FileSystemLike.wrapFile(root, root); | ||
| assertTrue(self.getPath().isEmpty()); | ||
| assertTrue(self.isDirectory()); | ||
|
|
||
| // URI round trip must not decode the name twice | ||
| java.nio.file.Path encoded = Files.createFile(tempPath.resolve("a b%20c.txt")); | ||
| FileLike e = FileSystemLike.wrapFile(root, encoded.toFile()); | ||
| assertEquals(1, e.getPath().size()); | ||
| assertEquals("a b%20c.txt", e.getName()); | ||
| assertTrue(e.isFile()); | ||
|
|
||
| assertThrows(FileNotFoundException.class, () -> FileSystemLike.wrapFile(nested.toFile(), nested.toFile())); | ||
|
|
||
| if (!System.getProperty("os.name").toLowerCase().startsWith("windows")) | ||
| { | ||
| // '\' is an ordinary file name character here | ||
| java.nio.file.Path backslash = Files.createFile(tempPath.resolve("a\\b.txt")); | ||
| FileLike f = FileSystemLike.wrapFile(root, backslash.toFile()); | ||
| assertEquals(1, f.getPath().size()); | ||
| assertEquals("a\\b.txt", f.getName()); | ||
| assertTrue(f.isFile()); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| void resolve(FileSystemLike fs) | ||
| { | ||
| FileLike root = fs.getRoot(); | ||
| FileLike a = root.resolveChild("a"); | ||
| assertEquals(a, root.resolveFile(Path.parse("b/../a"))); | ||
| assertEquals("b.txt", a.resolveFile(new Path("b.txt")).getName()); | ||
|
|
||
| // a Path part is a single file name, never a path | ||
| for (String name : new String[] {"../x", "a/../../x", "a/b", "/x"}) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Could the single-file-name check move into shared code (e.g.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll check on this. I focussed on FileSystemLocal because the root issue is local windows fs supporting an alternate path separator in nio.Path. Not sure this applies anywhere else. |
||
| assertThrows(name, FileUtil.InvalidPathReferenceException.class, () -> a.resolveFile(new Path(name))); | ||
| for (String name : new String[] {"..", "../x", "a/b"}) | ||
| assertThrows(name, FileUtil.InvalidPathReferenceException.class, () -> a.resolveChild(name)); | ||
| assertThrows(FileUtil.InvalidPathReferenceException.class, () -> a.resolveFile(Path.parse("../../x"))); | ||
| } | ||
|
|
||
| void list(FileSystemLike fs) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good strengthening but three callers that probably need matching updates:
SequenceAnalysisController.java:1076and:2234:resolveFile(new Path(form.getPath()))FeeScheduleController.java:176:allowedRoot.resolveFile(new Path(relativeURI.getPath())), the same pattern this PR fixed inFileSystemLike.getVerifiedFileLikeCould those switch to
Path.parse(...)in companion PRs?