8011128: (fs) Files.createDirectory fails if the resolved path is exactly 248 characters long
Reviewed-by: khazra, chegar
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java Fri May 10 10:20:13 2013 +0200
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileCopy.java Fri May 10 14:53:33 2013 +0100
@@ -224,7 +224,7 @@
String linkTarget = WindowsLinkSupport.readLink(source);
int flags = SYMBOLIC_LINK_FLAG_DIRECTORY;
CreateSymbolicLink(targetPath,
- addPrefixIfNeeded(linkTarget),
+ WindowsPath.addPrefixIfNeeded(linkTarget),
flags);
}
} catch (WindowsException x) {
@@ -414,7 +414,7 @@
} else {
String linkTarget = WindowsLinkSupport.readLink(source);
CreateSymbolicLink(targetPath,
- addPrefixIfNeeded(linkTarget),
+ WindowsPath.addPrefixIfNeeded(linkTarget),
SYMBOLIC_LINK_FLAG_DIRECTORY);
}
} catch (WindowsException x) {
@@ -502,18 +502,4 @@
priv.drop();
}
}
-
- /**
- * Add long path prefix to path if required
- */
- private static String addPrefixIfNeeded(String path) {
- if (path.length() > 248) {
- if (path.startsWith("\\\\")) {
- path = "\\\\?\\UNC" + path.substring(1, path.length());
- } else {
- path = "\\\\?\\" + path;
- }
- }
- return path;
- }
}
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java Fri May 10 10:20:13 2013 +0200
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsLinkSupport.java Fri May 10 14:53:33 2013 +0100
@@ -231,7 +231,7 @@
int end = (next == -1) ? path.length() : next;
String search = sb.toString() + path.substring(curr, end);
try {
- FirstFile fileData = FindFirstFile(addLongPathPrefixIfNeeded(search));
+ FirstFile fileData = FindFirstFile(WindowsPath.addPrefixIfNeeded(search));
FindClose(fileData.handle());
// if a reparse point is encountered then we must return the
@@ -406,20 +406,6 @@
}
/**
- * Add long path prefix to path if required.
- */
- private static String addLongPathPrefixIfNeeded(String path) {
- if (path.length() > 248) {
- if (path.startsWith("\\\\")) {
- path = "\\\\?\\UNC" + path.substring(1, path.length());
- } else {
- path = "\\\\?\\" + path;
- }
- }
- return path;
- }
-
- /**
* Strip long path or symbolic link prefix from path
*/
private static String stripPrefix(String path) {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java Fri May 10 10:20:13 2013 +0200
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsPath.java Fri May 10 14:53:33 2013 +0100
@@ -283,7 +283,7 @@
// Add long path prefix to path if required
static String addPrefixIfNeeded(String path) {
- if (path.length() > 248) {
+ if (path.length() > MAX_PATH) {
if (path.startsWith("\\\\")) {
path = "\\\\?\\UNC" + path.substring(1, path.length());
} else {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/NameLimits.java Fri May 10 14:53:33 2013 +0100
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8011128
+ * @summary Test file and directory name limits. This test is primarily
+ * intended to test Files.createDirectory on resolved paths at or around
+ * the short path limit of 248 on Windows.
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class NameLimits {
+
+ static final int MAX_PATH = 255;
+ static final int MIN_PATH = 8; // arbitrarily chosen
+
+ static Path generatePath(int len) {
+ if (len < MIN_PATH)
+ throw new RuntimeException("Attempting to generate path less than MIN_PATH");
+ StringBuilder sb = new StringBuilder(len);
+ sb.append("name");
+ while (sb.length() < len) {
+ sb.append('X');
+ }
+ return Paths.get(sb.toString());
+ }
+
+ static boolean tryCreateFile(int len) throws IOException {
+ Path name = generatePath(len);
+ try {
+ Files.createFile(name);
+ } catch (IOException ioe) {
+ System.err.format("Unable to create file of length %d (full path %d), %s%n",
+ name.toString().length(), name.toAbsolutePath().toString().length(), ioe);
+ return false;
+ }
+ Files.delete(name);
+ return true;
+ }
+
+ static boolean tryCreateDirectory(int len) throws IOException {
+ Path name = generatePath(len);
+ try {
+ Files.createDirectory(name);
+ } catch (IOException ioe) {
+ System.err.format("Unable to create directory of length %d (full path %d), %s%n",
+ name.toString().length(), name.toAbsolutePath().toString().length(), ioe);
+ return false;
+ }
+ Files.delete(name);
+ return true;
+ }
+
+ public static void main(String[] args) throws Exception {
+ int len;
+
+ // find the maximum file name if MAX_PATH or less
+ len = MAX_PATH;
+ while (!tryCreateFile(len)) {
+ len--;
+ }
+ System.out.format("Testing createFile on paths %d .. %d%n", MIN_PATH, len);
+ while (len >= MIN_PATH) {
+ if (!tryCreateFile(len--))
+ throw new RuntimeException("Test failed");
+ }
+
+ // find the maximum directory name if MAX_PATH or less
+ len = MAX_PATH;
+ while (!tryCreateDirectory(len)) {
+ len--;
+ }
+ System.out.format("Testing createDirectory on paths %d .. %d%n", MIN_PATH, len);
+ while (len >= MIN_PATH) {
+ if (!tryCreateDirectory(len--))
+ throw new RuntimeException("Test failed");
+ }
+ }
+}