8306882: (fs) Path.toRealPath(LinkOption.NOFOLLOW_LINKS) fails when "../../" follows a link

Reviewed-by: alanb
This commit is contained in:
Brian Burkhalter 2023-08-31 21:14:22 +00:00
parent 2436fb010e
commit 63f561fac2
3 changed files with 67 additions and 7 deletions

View file

@ -888,8 +888,15 @@ class UnixPath implements Path {
}
// 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);
@ -898,7 +905,7 @@ class UnixPath implements Path {
(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] == '.'))
@ -909,13 +916,16 @@ class UnixPath implements Path {
} 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);
}