7029979: (fs) Path.toRealPath(boolean) should be toRealPath(LinkOption...)
Reviewed-by: sherman
This commit is contained in:
parent
24ab596494
commit
fba270080e
jdk
src
share
classes
demo/nio/zipfs/src/com/sun/nio/zipfs
solaris/classes/sun/nio/fs
LinuxFileSystemProvider.javaSolarisFileSystemProvider.javaUnixFileSystemProvider.javaUnixPath.javaUnixSecureDirectoryStream.java
windows/classes/sun/nio/fs
test/java/nio/file
@ -550,18 +550,21 @@ public interface Path
|
||||
* <p> If this path is relative then its absolute path is first obtained,
|
||||
* as if by invoking the {@link #toAbsolutePath toAbsolutePath} method.
|
||||
*
|
||||
* <p> The {@code resolveLinks} parameter specifies if symbolic links
|
||||
* should be resolved. This parameter is ignored when symbolic links are
|
||||
* not supported. Where supported, and the parameter has the value {@code
|
||||
* true} then symbolic links are resolved to their final target. Where the
|
||||
* parameter has the value {@code false} then this method does not resolve
|
||||
* symbolic links. Some implementations allow special names such as
|
||||
* "{@code ..}" to refer to the parent directory. When deriving the <em>real
|
||||
* path</em>, and a "{@code ..}" (or equivalent) is preceded by a
|
||||
* non-"{@code ..}" name then an implementation will typically causes both
|
||||
* names to be removed. When not resolving symbolic links and the preceding
|
||||
* name is a symbolic link then the names are only removed if it guaranteed
|
||||
* that the resulting path will locate the same file as this path.
|
||||
* <p> The {@code options} array may be used to indicate how symbolic links
|
||||
* are handled. By default, symbolic links are resolved to their final
|
||||
* target. If the option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is
|
||||
* present then this method does not resolve symbolic links.
|
||||
*
|
||||
* Some implementations allow special names such as "{@code ..}" to refer to
|
||||
* the parent directory. When deriving the <em>real path</em>, and a
|
||||
* "{@code ..}" (or equivalent) is preceded by a non-"{@code ..}" name then
|
||||
* an implementation will typically cause both names to be removed. When
|
||||
* not resolving symbolic links and the preceding name is a symbolic link
|
||||
* then the names are only removed if it guaranteed that the resulting path
|
||||
* will locate the same file as this path.
|
||||
*
|
||||
* @param options
|
||||
* options indicating how symbolic links are handled
|
||||
*
|
||||
* @return an absolute path represent the <em>real</em> path of the file
|
||||
* located by this object
|
||||
@ -576,7 +579,7 @@ public interface Path
|
||||
* checkPropertyAccess} method is invoked to check access to the
|
||||
* system property {@code user.dir}
|
||||
*/
|
||||
Path toRealPath(boolean resolveLinks) throws IOException;
|
||||
Path toRealPath(LinkOption... options) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns a {@link File} object representing this path. Where this {@code
|
||||
|
@ -26,6 +26,7 @@
|
||||
package sun.nio.fs;
|
||||
|
||||
import java.util.*;
|
||||
import java.nio.file.*;
|
||||
|
||||
/**
|
||||
* Utility methods
|
||||
@ -80,4 +81,21 @@ class Util {
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if symbolic links should be followed
|
||||
*/
|
||||
static boolean followLinks(LinkOption... options) {
|
||||
boolean followLinks = true;
|
||||
for (LinkOption option: options) {
|
||||
if (option == LinkOption.NOFOLLOW_LINKS) {
|
||||
followLinks = false;
|
||||
} else if (option == null) {
|
||||
throw new NullPointerException();
|
||||
} else {
|
||||
throw new AssertionError("Should not get here");
|
||||
}
|
||||
}
|
||||
return followLinks;
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +479,7 @@ public class ZoneInfoFile {
|
||||
String zi = System.getProperty("java.home") +
|
||||
File.separator + "lib" + File.separator + "zi";
|
||||
try {
|
||||
zi = FileSystems.getDefault().getPath(zi).toRealPath(true).toString();
|
||||
zi = FileSystems.getDefault().getPath(zi).toRealPath().toString();
|
||||
} catch(Exception e) {
|
||||
}
|
||||
return zi;
|
||||
|
@ -99,7 +99,7 @@ public class ZipFileSystemProvider extends FileSystemProvider {
|
||||
synchronized(filesystems) {
|
||||
Path realPath = null;
|
||||
if (ensureFile(path)) {
|
||||
realPath = path.toRealPath(true);
|
||||
realPath = path.toRealPath();
|
||||
if (filesystems.containsKey(realPath))
|
||||
throw new FileSystemAlreadyExistsException();
|
||||
}
|
||||
@ -154,7 +154,7 @@ public class ZipFileSystemProvider extends FileSystemProvider {
|
||||
synchronized (filesystems) {
|
||||
ZipFileSystem zipfs = null;
|
||||
try {
|
||||
zipfs = filesystems.get(uriToPath(uri).toRealPath(true));
|
||||
zipfs = filesystems.get(uriToPath(uri).toRealPath());
|
||||
} catch (IOException x) {
|
||||
// ignore the ioe from toRealPath(), return FSNFE
|
||||
}
|
||||
@ -310,7 +310,7 @@ public class ZipFileSystemProvider extends FileSystemProvider {
|
||||
//////////////////////////////////////////////////////////////
|
||||
void removeFileSystem(Path zfpath, ZipFileSystem zfs) throws IOException {
|
||||
synchronized (filesystems) {
|
||||
zfpath = zfpath.toRealPath(true);
|
||||
zfpath = zfpath.toRealPath();
|
||||
if (filesystems.get(zfpath) == zfs)
|
||||
filesystems.remove(zfpath);
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ public class ZipPath implements Path {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZipPath toRealPath(boolean resolveLinks) throws IOException {
|
||||
public ZipPath toRealPath(LinkOption... options) throws IOException {
|
||||
ZipPath realPath = new ZipPath(zfs, getResolvedPath()).toAbsolutePath();
|
||||
realPath.checkAccess();
|
||||
return realPath;
|
||||
|
@ -56,11 +56,11 @@ public class LinuxFileSystemProvider extends UnixFileSystemProvider {
|
||||
{
|
||||
if (type == DosFileAttributeView.class) {
|
||||
return (V) new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
|
||||
followLinks(options));
|
||||
Util.followLinks(options));
|
||||
}
|
||||
if (type == UserDefinedFileAttributeView.class) {
|
||||
return (V) new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
|
||||
followLinks(options));
|
||||
Util.followLinks(options));
|
||||
}
|
||||
return super.getFileAttributeView(obj, type, options);
|
||||
}
|
||||
@ -72,11 +72,11 @@ public class LinuxFileSystemProvider extends UnixFileSystemProvider {
|
||||
{
|
||||
if (name.equals("dos")) {
|
||||
return new LinuxDosFileAttributeView(UnixPath.toUnixPath(obj),
|
||||
followLinks(options));
|
||||
Util.followLinks(options));
|
||||
}
|
||||
if (name.equals("user")) {
|
||||
return new LinuxUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
|
||||
followLinks(options));
|
||||
Util.followLinks(options));
|
||||
}
|
||||
return super.getFileAttributeView(obj, name, options);
|
||||
}
|
||||
|
@ -57,11 +57,11 @@ public class SolarisFileSystemProvider extends UnixFileSystemProvider {
|
||||
{
|
||||
if (type == AclFileAttributeView.class) {
|
||||
return (V) new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
|
||||
followLinks(options));
|
||||
Util.followLinks(options));
|
||||
}
|
||||
if (type == UserDefinedFileAttributeView.class) {
|
||||
return(V) new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
|
||||
followLinks(options));
|
||||
Util.followLinks(options));
|
||||
}
|
||||
return super.getFileAttributeView(obj, type, options);
|
||||
}
|
||||
@ -73,10 +73,10 @@ public class SolarisFileSystemProvider extends UnixFileSystemProvider {
|
||||
{
|
||||
if (name.equals("acl"))
|
||||
return new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj),
|
||||
followLinks(options));
|
||||
Util.followLinks(options));
|
||||
if (name.equals("user"))
|
||||
return new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
|
||||
followLinks(options));
|
||||
Util.followLinks(options));
|
||||
return super.getFileAttributeView(obj, name, options);
|
||||
}
|
||||
}
|
||||
|
@ -105,20 +105,6 @@ public abstract class UnixFileSystemProvider
|
||||
return (UnixPath)obj;
|
||||
}
|
||||
|
||||
boolean followLinks(LinkOption... options) {
|
||||
boolean followLinks = true;
|
||||
for (LinkOption option: options) {
|
||||
if (option == LinkOption.NOFOLLOW_LINKS) {
|
||||
followLinks = false;
|
||||
continue;
|
||||
}
|
||||
if (option == null)
|
||||
throw new NullPointerException();
|
||||
throw new AssertionError("Should not get here");
|
||||
}
|
||||
return followLinks;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <V extends FileAttributeView> V getFileAttributeView(Path obj,
|
||||
@ -126,7 +112,7 @@ public abstract class UnixFileSystemProvider
|
||||
LinkOption... options)
|
||||
{
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
boolean followLinks = followLinks(options);
|
||||
boolean followLinks = Util.followLinks(options);
|
||||
if (type == BasicFileAttributeView.class)
|
||||
return (V) UnixFileAttributeViews.createBasicView(file, followLinks);
|
||||
if (type == PosixFileAttributeView.class)
|
||||
@ -163,7 +149,7 @@ public abstract class UnixFileSystemProvider
|
||||
LinkOption... options)
|
||||
{
|
||||
UnixPath file = UnixPath.toUnixPath(obj);
|
||||
boolean followLinks = followLinks(options);
|
||||
boolean followLinks = Util.followLinks(options);
|
||||
if (name.equals("basic"))
|
||||
return UnixFileAttributeViews.createBasicView(file, followLinks);
|
||||
if (name.equals("posix"))
|
||||
|
@ -819,13 +819,13 @@ class UnixPath
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path toRealPath(boolean resolveLinks) throws IOException {
|
||||
public Path toRealPath(LinkOption... options) throws IOException {
|
||||
checkRead();
|
||||
|
||||
UnixPath absolute = toAbsolutePath();
|
||||
|
||||
// if resolveLinks is true then use realpath
|
||||
if (resolveLinks) {
|
||||
// if resolving links then use realpath
|
||||
if (Util.followLinks(options)) {
|
||||
try {
|
||||
byte[] rp = realpath(absolute);
|
||||
return new UnixPath(getFileSystem(), rp);
|
||||
@ -834,7 +834,7 @@ class UnixPath
|
||||
}
|
||||
}
|
||||
|
||||
// if resolveLinks is false then eliminate "." and also ".."
|
||||
// if not resolving links then eliminate "." and also ".."
|
||||
// where the previous element is not a link.
|
||||
UnixPath result = fs.rootDirectory();
|
||||
for (int i=0; i<absolute.getNameCount(); i++) {
|
||||
|
@ -81,20 +81,6 @@ class UnixSecureDirectoryStream
|
||||
return (UnixPath)obj;
|
||||
}
|
||||
|
||||
private boolean followLinks(LinkOption... options) {
|
||||
boolean followLinks = true;
|
||||
for (LinkOption option: options) {
|
||||
if (option == LinkOption.NOFOLLOW_LINKS) {
|
||||
followLinks = false;
|
||||
continue;
|
||||
}
|
||||
if (option == null)
|
||||
throw new NullPointerException();
|
||||
throw new AssertionError("Should not get here");
|
||||
}
|
||||
return followLinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens sub-directory in this directory
|
||||
*/
|
||||
@ -105,7 +91,7 @@ class UnixSecureDirectoryStream
|
||||
{
|
||||
UnixPath file = getName(obj);
|
||||
UnixPath child = ds.directory().resolve(file);
|
||||
boolean followLinks = followLinks(options);
|
||||
boolean followLinks = Util.followLinks(options);
|
||||
|
||||
// permission check using name resolved against original path of directory
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
@ -316,7 +302,7 @@ class UnixSecureDirectoryStream
|
||||
LinkOption... options)
|
||||
{
|
||||
UnixPath file = getName(obj);
|
||||
boolean followLinks = followLinks(options);
|
||||
boolean followLinks = Util.followLinks(options);
|
||||
return getFileAttributeViewImpl(file, type, followLinks);
|
||||
}
|
||||
|
||||
|
@ -150,20 +150,6 @@ public class WindowsFileSystemProvider
|
||||
}
|
||||
}
|
||||
|
||||
private boolean followLinks(LinkOption... options) {
|
||||
boolean followLinks = true;
|
||||
for (LinkOption option: options) {
|
||||
if (option == LinkOption.NOFOLLOW_LINKS) {
|
||||
followLinks = false;
|
||||
continue;
|
||||
}
|
||||
if (option == null)
|
||||
throw new NullPointerException();
|
||||
throw new AssertionError("Should not get here");
|
||||
}
|
||||
return followLinks;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <V extends FileAttributeView> V
|
||||
@ -172,7 +158,7 @@ public class WindowsFileSystemProvider
|
||||
WindowsPath file = WindowsPath.toWindowsPath(obj);
|
||||
if (view == null)
|
||||
throw new NullPointerException();
|
||||
boolean followLinks = followLinks(options);
|
||||
boolean followLinks = Util.followLinks(options);
|
||||
if (view == BasicFileAttributeView.class)
|
||||
return (V) WindowsFileAttributeViews.createBasicView(file, followLinks);
|
||||
if (view == DosFileAttributeView.class)
|
||||
@ -209,7 +195,7 @@ public class WindowsFileSystemProvider
|
||||
@Override
|
||||
public DynamicFileAttributeView getFileAttributeView(Path obj, String name, LinkOption... options) {
|
||||
WindowsPath file = WindowsPath.toWindowsPath(obj);
|
||||
boolean followLinks = followLinks(options);
|
||||
boolean followLinks = Util.followLinks(options);
|
||||
if (name.equals("basic"))
|
||||
return WindowsFileAttributeViews.createBasicView(file, followLinks);
|
||||
if (name.equals("dos"))
|
||||
|
@ -831,9 +831,9 @@ class WindowsPath extends AbstractPath {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowsPath toRealPath(boolean resolveLinks) throws IOException {
|
||||
public WindowsPath toRealPath(LinkOption... options) throws IOException {
|
||||
checkRead();
|
||||
String rp = WindowsLinkSupport.getRealPath(this, resolveLinks);
|
||||
String rp = WindowsLinkSupport.getRealPath(this, Util.followLinks(options));
|
||||
return createFromNormalizedPath(getFileSystem(), rp);
|
||||
}
|
||||
|
||||
|
@ -521,19 +521,19 @@ public class CheckPermissions {
|
||||
// -- toRealPath --
|
||||
|
||||
prepare();
|
||||
file.toRealPath(true);
|
||||
file.toRealPath();
|
||||
assertCheckRead(file);
|
||||
|
||||
prepare();
|
||||
file.toRealPath(false);
|
||||
file.toRealPath(LinkOption.NOFOLLOW_LINKS);
|
||||
assertCheckRead(file);
|
||||
|
||||
prepare();
|
||||
Paths.get(".").toRealPath(true);
|
||||
Paths.get(".").toRealPath();
|
||||
assertCheckPropertyAccess("user.dir");
|
||||
|
||||
prepare();
|
||||
Paths.get(".").toRealPath(false);
|
||||
Paths.get(".").toRealPath(LinkOption.NOFOLLOW_LINKS);
|
||||
assertCheckPropertyAccess("user.dir");
|
||||
|
||||
// -- register --
|
||||
|
@ -486,8 +486,8 @@ class PassThroughFileSystem extends FileSystem {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path toRealPath(boolean resolveLinks) throws IOException {
|
||||
return wrap(delegate.toRealPath(resolveLinks));
|
||||
public Path toRealPath(LinkOption... options) throws IOException {
|
||||
return wrap(delegate.toRealPath(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,12 +22,13 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4313887 6838333
|
||||
* @bug 4313887 6838333 7029979
|
||||
* @summary Unit test for miscellenous java.nio.file.Path methods
|
||||
* @library ..
|
||||
*/
|
||||
|
||||
import java.nio.file.*;
|
||||
import static java.nio.file.LinkOption.*;
|
||||
import java.io.*;
|
||||
|
||||
public class Misc {
|
||||
@ -96,65 +97,65 @@ public class Misc {
|
||||
final Path link = dir.resolve("link");
|
||||
|
||||
/**
|
||||
* Test: totRealPath(true) will access same file as toRealPath(false)
|
||||
* Test: totRealPath() will access same file as toRealPath(NOFOLLOW_LINKS)
|
||||
*/
|
||||
assertTrue(Files.isSameFile(file.toRealPath(true), file.toRealPath(false)));
|
||||
assertTrue(Files.isSameFile(file.toRealPath(), file.toRealPath(NOFOLLOW_LINKS)));
|
||||
|
||||
/**
|
||||
* Test: toRealPath should fail if file does not exist
|
||||
*/
|
||||
Path doesNotExist = dir.resolve("DoesNotExist");
|
||||
try {
|
||||
doesNotExist.toRealPath(true);
|
||||
doesNotExist.toRealPath();
|
||||
throw new RuntimeException("IOException expected");
|
||||
} catch (IOException expected) {
|
||||
}
|
||||
try {
|
||||
doesNotExist.toRealPath(false);
|
||||
doesNotExist.toRealPath(NOFOLLOW_LINKS);
|
||||
throw new RuntimeException("IOException expected");
|
||||
} catch (IOException expected) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: toRealPath(true) should resolve links
|
||||
* Test: toRealPath() should resolve links
|
||||
*/
|
||||
if (supportsLinks) {
|
||||
Files.createSymbolicLink(link, file.toAbsolutePath());
|
||||
assertTrue(link.toRealPath(true).equals(file.toRealPath(true)));
|
||||
assertTrue(link.toRealPath().equals(file.toRealPath()));
|
||||
Files.delete(link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: toRealPath(false) should not resolve links
|
||||
* Test: toRealPath(NOFOLLOW_LINKS) should not resolve links
|
||||
*/
|
||||
if (supportsLinks) {
|
||||
Files.createSymbolicLink(link, file.toAbsolutePath());
|
||||
assertTrue(link.toRealPath(false).getFileName().equals(link.getFileName()));
|
||||
assertTrue(link.toRealPath(NOFOLLOW_LINKS).getFileName().equals(link.getFileName()));
|
||||
Files.delete(link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: toRealPath(false) with broken link
|
||||
* Test: toRealPath(NOFOLLOW_LINKS) with broken link
|
||||
*/
|
||||
if (supportsLinks) {
|
||||
Path broken = Files.createSymbolicLink(link, doesNotExist);
|
||||
assertTrue(link.toRealPath(false).getFileName().equals(link.getFileName()));
|
||||
assertTrue(link.toRealPath(NOFOLLOW_LINKS).getFileName().equals(link.getFileName()));
|
||||
Files.delete(link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: toRealPath should eliminate "."
|
||||
*/
|
||||
assertTrue(dir.resolve(".").toRealPath(true).equals(dir.toRealPath(true)));
|
||||
assertTrue(dir.resolve(".").toRealPath(false).equals(dir.toRealPath(false)));
|
||||
assertTrue(dir.resolve(".").toRealPath().equals(dir.toRealPath()));
|
||||
assertTrue(dir.resolve(".").toRealPath(NOFOLLOW_LINKS).equals(dir.toRealPath(NOFOLLOW_LINKS)));
|
||||
|
||||
/**
|
||||
* Test: toRealPath should eliminate ".." when it doesn't follow a
|
||||
* symbolic link
|
||||
*/
|
||||
Path subdir = Files.createDirectory(dir.resolve("subdir"));
|
||||
assertTrue(subdir.resolve("..").toRealPath(true).equals(dir.toRealPath(true)));
|
||||
assertTrue(subdir.resolve("..").toRealPath(false).equals(dir.toRealPath(false)));
|
||||
assertTrue(subdir.resolve("..").toRealPath().equals(dir.toRealPath()));
|
||||
assertTrue(subdir.resolve("..").toRealPath(NOFOLLOW_LINKS).equals(dir.toRealPath(NOFOLLOW_LINKS)));
|
||||
Files.delete(subdir);
|
||||
|
||||
// clean-up
|
||||
|
Loading…
x
Reference in New Issue
Block a user