提交 253eae09 编写于 作者: A alanb

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

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