mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8276661: (fs) UserDefinedFileAttributeView no longer works with long path (win)
Reviewed-by: alanb
This commit is contained in:
parent
652b5f8546
commit
15345e3edc
3 changed files with 42 additions and 24 deletions
|
@ -174,38 +174,48 @@ class WindowsPath implements Path {
|
||||||
// use this path for Win32 calls
|
// use this path for Win32 calls
|
||||||
// This method will prefix long paths with \\?\ or \\?\UNC as required.
|
// This method will prefix long paths with \\?\ or \\?\UNC as required.
|
||||||
String getPathForWin32Calls() throws WindowsException {
|
String getPathForWin32Calls() throws WindowsException {
|
||||||
// short absolute paths can be used directly
|
return getPathForWin32Calls(true);
|
||||||
if (isAbsolute() && path.length() <= MAX_PATH)
|
}
|
||||||
return path;
|
|
||||||
|
|
||||||
// return cached values if available
|
String getPathWithPrefixForWin32Calls() throws WindowsException {
|
||||||
WeakReference<String> ref = pathForWin32Calls;
|
return getPathForWin32Calls(false);
|
||||||
String resolved = (ref != null) ? ref.get() : null;
|
}
|
||||||
if (resolved != null) {
|
|
||||||
// Win32 path already available
|
private String getPathForWin32Calls(boolean allowShortPath) throws WindowsException {
|
||||||
return resolved;
|
if (allowShortPath) {
|
||||||
|
// short absolute paths can be used directly
|
||||||
|
if (isAbsolute() && path.length() <= MAX_PATH)
|
||||||
|
return path;
|
||||||
|
|
||||||
|
// returned cached value if possible
|
||||||
|
WeakReference<String> ref = pathForWin32Calls;
|
||||||
|
String cached = (ref != null) ? ref.get() : null;
|
||||||
|
if (cached != null) {
|
||||||
|
// Win32 path already available
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve against default directory
|
// resolve against default directory
|
||||||
resolved = getAbsolutePath();
|
String resolved = getAbsolutePath();
|
||||||
|
|
||||||
// Long paths need to have "." and ".." removed and be prefixed with
|
// Long paths need to have "." and ".." removed and be prefixed with
|
||||||
// "\\?\". Note that it is okay to remove ".." even when it follows
|
// "\\?\". Note that it is okay to remove ".." even when it follows
|
||||||
// a link - for example, it is okay for foo/link/../bar to be changed
|
// a link - for example, it is okay for foo/link/../bar to be changed
|
||||||
// to foo/bar. The reason is that Win32 APIs to access foo/link/../bar
|
// to foo/bar. The reason is that Win32 APIs to access foo/link/../bar
|
||||||
// will access foo/bar anyway (which differs to Unix systems)
|
// will access foo/bar anyway (which differs to Unix systems)
|
||||||
if (resolved.length() > MAX_PATH) {
|
if (resolved.length() > MAX_PATH || !allowShortPath) {
|
||||||
if (resolved.length() > MAX_LONG_PATH) {
|
if (resolved.length() > MAX_LONG_PATH) {
|
||||||
throw new WindowsException("Cannot access file with path exceeding "
|
throw new WindowsException("Cannot access file with path exceeding "
|
||||||
+ MAX_LONG_PATH + " characters");
|
+ MAX_LONG_PATH + " characters");
|
||||||
}
|
}
|
||||||
resolved = addPrefixIfNeeded(GetFullPathName(resolved));
|
resolved = addPrefix(GetFullPathName(resolved));
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache the resolved path (except drive relative paths as the working
|
// cache the resolved path (except drive relative paths as the working
|
||||||
// directory on removal media devices can change during the lifetime
|
// directory on removal media devices can change during the lifetime
|
||||||
// of the VM)
|
// of the VM)
|
||||||
if (type != WindowsPathType.DRIVE_RELATIVE) {
|
if (allowShortPath && type != WindowsPathType.DRIVE_RELATIVE) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
pathForWin32Calls = new WeakReference<String>(resolved);
|
pathForWin32Calls = new WeakReference<String>(resolved);
|
||||||
}
|
}
|
||||||
|
@ -279,14 +289,20 @@ class WindowsPath implements Path {
|
||||||
Character.toUpperCase(root2.charAt(0));
|
Character.toUpperCase(root2.charAt(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add long path prefix to path
|
||||||
|
static String addPrefix(String path) {
|
||||||
|
if (path.startsWith("\\\\")) {
|
||||||
|
path = "\\\\?\\UNC" + path.substring(1, path.length());
|
||||||
|
} else {
|
||||||
|
path = "\\\\?\\" + path;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
// Add long path prefix to path if required
|
// Add long path prefix to path if required
|
||||||
static String addPrefixIfNeeded(String path) {
|
static String addPrefixIfNeeded(String path) {
|
||||||
if (path.length() > MAX_PATH) {
|
if (path.length() > MAX_PATH) {
|
||||||
if (path.startsWith("\\\\")) {
|
return addPrefix(path);
|
||||||
path = "\\\\?\\UNC" + path.substring(1, path.length());
|
|
||||||
} else {
|
|
||||||
path = "\\\\?\\" + path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,9 +61,7 @@ class WindowsUserDefinedFileAttributeView
|
||||||
throw new IllegalArgumentException("'name' has a root component");
|
throw new IllegalArgumentException("'name' has a root component");
|
||||||
if (namePath.getParent() != null)
|
if (namePath.getParent() != null)
|
||||||
throw new IllegalArgumentException("'name' has more than one element");
|
throw new IllegalArgumentException("'name' has more than one element");
|
||||||
String path = join(file.getPathForWin32Calls(), name);
|
return join(file.getPathWithPrefixForWin32Calls(), name);
|
||||||
WindowsPath wp = WindowsPath.createFromNormalizedPath(wfs, path);
|
|
||||||
return wp.getPathForWin32Calls();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final WindowsPath file;
|
private final WindowsPath file;
|
||||||
|
|
|
@ -242,7 +242,7 @@ public class Basic {
|
||||||
|
|
||||||
// We need to run up to MAX_PATH for directories,
|
// We need to run up to MAX_PATH for directories,
|
||||||
// but not quite go over it.
|
// but not quite go over it.
|
||||||
int MAX_PATH = 247;
|
int MAX_PATH = 250;
|
||||||
int requiredLen = MAX_PATH - len - 2;
|
int requiredLen = MAX_PATH - len - 2;
|
||||||
|
|
||||||
// Create a really long directory name.
|
// Create a really long directory name.
|
||||||
|
@ -252,11 +252,15 @@ public class Basic {
|
||||||
Files.createDirectory(longPath);
|
Files.createDirectory(longPath);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Try to set absolute path as extended attribute; expect IAE
|
System.out.println("Testing " + longPath);
|
||||||
|
|
||||||
|
// Try to set absolute path as extended attribute;
|
||||||
|
// expect IAE
|
||||||
tryCatch(IllegalArgumentException.class, new Task() {
|
tryCatch(IllegalArgumentException.class, new Task() {
|
||||||
public void run() throws IOException {
|
public void run() throws IOException {
|
||||||
setEA(longPath, "user:C:\\");
|
setEA(longPath, "user:C:\\");
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Try to set an extended attribute on it.
|
// Try to set an extended attribute on it.
|
||||||
setEA(longPath, "user:short");
|
setEA(longPath, "user:short");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue