mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 19:44:41 +02:00
6481955: Uncanonicalized absolute filepath with length 248-260 no longer works (win)
Uncanonicalized absolute filepath with length 248-260 no longer works (win) Reviewed-by: alanb
This commit is contained in:
parent
d1ff48eb56
commit
827decba87
2 changed files with 97 additions and 25 deletions
|
@ -104,23 +104,56 @@ currentDirLength(const WCHAR* ps, int pathlen) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The "abpathlen" is the size of the buffer needed by _wfullpath. If the
|
||||||
|
"path" is a relative path, it is "the length of the current dir" + "the
|
||||||
|
length of the path", if it's "absolute" already, it's the same as
|
||||||
|
pathlen which is the length of "path".
|
||||||
|
*/
|
||||||
|
WCHAR* prefixAbpath(const WCHAR* path, int pathlen, int abpathlen) {
|
||||||
|
WCHAR* pathbuf = NULL;
|
||||||
|
WCHAR* abpath = NULL;
|
||||||
|
|
||||||
|
abpathlen += 10; //padding
|
||||||
|
abpath = (WCHAR*)malloc(abpathlen * sizeof(WCHAR));
|
||||||
|
if (abpath) {
|
||||||
|
/* Collapse instances of "foo\.." and ensure absoluteness before
|
||||||
|
going down to prefixing.
|
||||||
|
*/
|
||||||
|
if (_wfullpath(abpath, path, abpathlen)) {
|
||||||
|
pathbuf = getPrefixed(abpath, abpathlen);
|
||||||
|
} else {
|
||||||
|
/* _wfullpath fails if the pathlength exceeds 32k wchar.
|
||||||
|
Instead of doing more fancy things we simply copy the
|
||||||
|
ps into the return buffer, the subsequent win32 API will
|
||||||
|
probably fail with FileNotFoundException, which is expected
|
||||||
|
*/
|
||||||
|
pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
|
||||||
|
if (pathbuf != 0) {
|
||||||
|
wcscpy(pathbuf, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(abpath);
|
||||||
|
}
|
||||||
|
return pathbuf;
|
||||||
|
}
|
||||||
|
|
||||||
/* If this returns NULL then an exception is pending */
|
/* If this returns NULL then an exception is pending */
|
||||||
WCHAR*
|
WCHAR*
|
||||||
pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) {
|
pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) {
|
||||||
int pathlen = 0;
|
int pathlen = 0;
|
||||||
WCHAR *pathbuf = NULL;
|
WCHAR *pathbuf = NULL;
|
||||||
int max_path = 248; /* Since CreateDirectoryW() has the limit of
|
int max_path = 248; /* CreateDirectoryW() has the limit of 248 */
|
||||||
248 instead of the normal MAX_PATH, we
|
|
||||||
use 248 as the max_path to satisfy both
|
|
||||||
*/
|
|
||||||
WITH_UNICODE_STRING(env, path, ps) {
|
WITH_UNICODE_STRING(env, path, ps) {
|
||||||
pathlen = wcslen(ps);
|
pathlen = wcslen(ps);
|
||||||
if (pathlen != 0) {
|
if (pathlen != 0) {
|
||||||
if (pathlen > 2 &&
|
if (pathlen > 2 &&
|
||||||
(ps[0] == L'\\' && ps[1] == L'\\' || //UNC
|
(ps[0] == L'\\' && ps[1] == L'\\' || //UNC
|
||||||
ps[1] == L':' && ps[2] == L'\\')) { //absolute
|
ps[1] == L':' && ps[2] == L'\\')) //absolute
|
||||||
|
{
|
||||||
if (pathlen > max_path - 1) {
|
if (pathlen > max_path - 1) {
|
||||||
pathbuf = getPrefixed(ps, pathlen);
|
pathbuf = prefixAbpath(ps, pathlen, pathlen);
|
||||||
} else {
|
} else {
|
||||||
pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
|
pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
|
||||||
if (pathbuf != 0) {
|
if (pathbuf != 0) {
|
||||||
|
@ -132,7 +165,7 @@ pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) {
|
||||||
its absolute form is bigger than max_path or not, if yes
|
its absolute form is bigger than max_path or not, if yes
|
||||||
need to (1)convert it to absolute and (2)prefix. This is
|
need to (1)convert it to absolute and (2)prefix. This is
|
||||||
obviously a burden to all relative paths (The current dir/len
|
obviously a burden to all relative paths (The current dir/len
|
||||||
for "dirve & directory" relative path is cached, so we only
|
for "drive & directory" relative path is cached, so we only
|
||||||
calculate it once but for "drive-relative path we call
|
calculate it once but for "drive-relative path we call
|
||||||
_wgetdcwd() and wcslen() everytime), but a hit we have
|
_wgetdcwd() and wcslen() everytime), but a hit we have
|
||||||
to take if we want to support relative path beyond max_path.
|
to take if we want to support relative path beyond max_path.
|
||||||
|
@ -143,24 +176,7 @@ pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) {
|
||||||
WCHAR *abpath = NULL;
|
WCHAR *abpath = NULL;
|
||||||
int dirlen = currentDirLength(ps, pathlen);
|
int dirlen = currentDirLength(ps, pathlen);
|
||||||
if (dirlen + pathlen + 1 > max_path - 1) {
|
if (dirlen + pathlen + 1 > max_path - 1) {
|
||||||
int abpathlen = dirlen + pathlen + 10;
|
pathbuf = prefixAbpath(ps, pathlen, dirlen + pathlen);
|
||||||
abpath = (WCHAR*)malloc(abpathlen * sizeof(WCHAR));
|
|
||||||
if (abpath) {
|
|
||||||
if (_wfullpath(abpath, ps, abpathlen)) {
|
|
||||||
pathbuf = getPrefixed(abpath, abpathlen);
|
|
||||||
} else {
|
|
||||||
/* _wfullpath fails if the pathlength exceeds 32k wchar.
|
|
||||||
Instead of doing more fancy things we simply copy the
|
|
||||||
ps into the return buffer, the subsequent win32 API will
|
|
||||||
probably fail with FileNotFoundException, which is expected
|
|
||||||
*/
|
|
||||||
pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
|
|
||||||
if (pathbuf != 0) {
|
|
||||||
wcscpy(pathbuf, ps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(abpath);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
|
pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
|
||||||
if (pathbuf != 0) {
|
if (pathbuf != 0) {
|
||||||
|
|
56
jdk/test/java/io/File/MaxPath.java
Normal file
56
jdk/test/java/io/File/MaxPath.java
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @test
|
||||||
|
@bug 6481955
|
||||||
|
@summary Path length less than MAX_PATH (260) works on Windows
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class MaxPath {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
String osName = System.getProperty("os.name");
|
||||||
|
if (!osName.startsWith("Windows")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int MAX_PATH = 260;
|
||||||
|
String dir = new File(".").getAbsolutePath() + "\\";
|
||||||
|
String padding = "1234567890123456789012345678901234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890";
|
||||||
|
for (int i = 240 - dir.length(); i < MAX_PATH - dir.length(); i++) {
|
||||||
|
String longname = dir + padding.substring(0, i);
|
||||||
|
try {
|
||||||
|
File f = new File(longname);
|
||||||
|
if (f.createNewFile()) {
|
||||||
|
if (!f.exists() || !f.canRead()) {
|
||||||
|
throw new RuntimeException("Failed at length: " + longname.length());
|
||||||
|
}
|
||||||
|
f.delete();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Failed at length: " + longname.length());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue