Skip to content

Commit

Permalink
8306882: (fs) Path.toRealPath(LinkOption.NOFOLLOW_LINKS) fails when "…
Browse files Browse the repository at this point in the history
…../../" follows a link

Reviewed-by: alanb
  • Loading branch information
Brian Burkhalter committed Aug 31, 2023
1 parent 2436fb0 commit 63f561f
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 7 deletions.
16 changes: 13 additions & 3 deletions src/java.base/unix/classes/sun/nio/fs/UnixPath.java
Original file line number Diff line number Diff line change
Expand Up @@ -888,8 +888,15 @@ public Path toRealPath(LinkOption... options) throws IOException {
}

// if not resolving links then eliminate "." and also ".."
// where the previous element is not a link.
// where the previous element is neither a link nor "..".
// if there is a preceding "..", then it might have followed
// a link or a link followed by a sequence of two or more "..".
// if for example one has the path "link/../../file",
// then if a preceding ".." were eliminated, then the result
// would be "<root>/link/file" instead of the correct
// "<root>/link/../../file".
UnixPath result = fs.rootDirectory();
boolean parentIsDotDot = false;
for (int i = 0; i < absolute.getNameCount(); i++) {
UnixPath element = absolute.getName(i);

Expand All @@ -898,7 +905,7 @@ public Path toRealPath(LinkOption... options) throws IOException {
(element.asByteArray()[0] == '.'))
continue;

// cannot eliminate ".." if previous element is a link
// cannot eliminate ".." if previous element is a link or ".."
if ((element.asByteArray().length == 2) &&
(element.asByteArray()[0] == '.') &&
(element.asByteArray()[1] == '.'))
Expand All @@ -909,13 +916,16 @@ public Path toRealPath(LinkOption... options) throws IOException {
} catch (UnixException x) {
x.rethrowAsIOException(result);
}
if (!attrs.isSymbolicLink()) {
if (!attrs.isSymbolicLink() && !parentIsDotDot) {
result = result.getParent();
if (result == null) {
result = fs.rootDirectory();
}
continue;
}
parentIsDotDot = true;
} else {
parentIsDotDot = false;
}
result = result.resolve(element);
}
Expand Down
6 changes: 4 additions & 2 deletions test/jdk/ProblemList.txt
Original file line number Diff line number Diff line change
Expand Up @@ -543,13 +543,15 @@ java/net/MulticastSocket/SetOutgoingIf.java 8308807 aix-ppc6

java/nio/channels/AsynchronousSocketChannel/StressLoopback.java 8211851 aix-ppc64

java/nio/channels/DatagramChannel/AfterDisconnect.java 8308807 aix-ppc64

java/nio/channels/DatagramChannel/ManySourcesAndTargets.java 8264385 macosx-aarch64

java/nio/channels/DatagramChannel/Unref.java 8233437 generic-all

jdk/nio/zipfs/TestLocOffsetFromZip64EF.java 8301183 linux-all
java/nio/file/Path/ToRealPath.java 8315273 windows-all

java/nio/channels/DatagramChannel/AfterDisconnect.java 8308807 aix-ppc64
jdk/nio/zipfs/TestLocOffsetFromZip64EF.java 8301183 linux-all

############################################################################

Expand Down
52 changes: 50 additions & 2 deletions test/jdk/java/nio/file/Path/ToRealPath.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*/

/* @test
* @bug 8295753
* @bug 8295753 8306882
* @summary Verify correct operation of Path.toRealPath
* @library .. /test/lib
* @build ToRealPath jdk.test.lib.Platform
Expand Down Expand Up @@ -142,6 +142,52 @@ public void eliminateDotsNoFollow() throws IOException {
DIR.toRealPath(NOFOLLOW_LINKS));
}

@Test
@EnabledIf("supportsLinks")
public void noCollapseDots1() throws IOException {
Path subPath = DIR.resolve(Path.of("dir", "subdir"));
Path sub = Files.createDirectories(subPath);
System.out.println("sub: " + sub);
Files.createSymbolicLink(LINK, sub);
System.out.println("LINK: " + LINK + " -> " + sub);
Path p = Path.of("..", "..", FILE.getFileName().toString());
System.out.println("p: " + p);
Path path = LINK.resolve(p);
System.out.println("path: " + path);
System.out.println("no follow: " + path.toRealPath(NOFOLLOW_LINKS));
assertEquals(path.toRealPath(NOFOLLOW_LINKS), path);

Files.delete(sub);
Files.delete(sub.getParent());
Files.delete(LINK);
}

@Test
@EnabledIf("supportsLinks")
public void noCollapseDots2() throws IOException {
Path subPath = DIR.resolve(Path.of("dir", "subdir"));
Path sub = Files.createDirectories(subPath);
Path out = Files.createFile(DIR.resolve(Path.of("out.txt")));
Path aaa = DIR.resolve(Path.of("aaa"));
Files.createSymbolicLink(aaa, sub);
System.out.println("aaa: " + aaa + " -> " + sub);
Path bbb = DIR.resolve(Path.of("bbb"));
Files.createSymbolicLink(bbb, sub);
System.out.println("bbb: " + bbb + " -> " + sub);
Path p = Path.of("aaa", "..", "..", "bbb", "..", "..", "out.txt");
Path path = DIR.resolve(p);
System.out.println("path: " + path);
System.out.println("no follow: " + path.toRealPath(NOFOLLOW_LINKS));
assertEquals(path.toRealPath(NOFOLLOW_LINKS), path);
System.out.println(path.toRealPath());

Files.delete(sub);
Files.delete(sub.getParent());
Files.delete(out);
Files.delete(aaa);
Files.delete(bbb);
}

@Test
@EnabledOnOs(OS.MAC)
public final void macOSTests() throws IOException {
Expand Down Expand Up @@ -180,12 +226,14 @@ public final void macOSTests() throws IOException {
assertEquals(noFollow.getName(nc - 4), Path.of("theLink"));
assertEquals(noFollow.getName(nc - 1), Path.of("theTarget"));

Files.delete(theLink);
Files.delete(theTarget);
}

@AfterAll
public static void cleanup() throws IOException {
Files.delete(SUBDIR);
Files.delete(FILE);
Files.delete(SUBDIR);
Files.delete(DIR);
}
}

1 comment on commit 63f561f

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.