7029979: (fs) Path.toRealPath(boolean) should be toRealPath(LinkOption...)

Reviewed-by: sherman
This commit is contained in:
Alan Bateman 2011-04-04 18:09:53 +01:00
parent 24ab596494
commit fba270080e
15 changed files with 81 additions and 101 deletions

@ -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