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
@ -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 */
|
||||
WCHAR*
|
||||
pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE) {
|
||||
int pathlen = 0;
|
||||
WCHAR *pathbuf = NULL;
|
||||
int max_path = 248; /* Since CreateDirectoryW() has the limit of
|
||||
248 instead of the normal MAX_PATH, we
|
||||
use 248 as the max_path to satisfy both
|
||||
*/
|
||||
int max_path = 248; /* CreateDirectoryW() has the limit of 248 */
|
||||
|
||||
WITH_UNICODE_STRING(env, path, ps) {
|
||||
pathlen = wcslen(ps);
|
||||
if (pathlen != 0) {
|
||||
if (pathlen > 2 &&
|
||||
(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) {
|
||||
pathbuf = getPrefixed(ps, pathlen);
|
||||
pathbuf = prefixAbpath(ps, pathlen, pathlen);
|
||||
} else {
|
||||
pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
|
||||
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
|
||||
need to (1)convert it to absolute and (2)prefix. This is
|
||||
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
|
||||
_wgetdcwd() and wcslen() everytime), but a hit we have
|
||||
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;
|
||||
int dirlen = currentDirLength(ps, pathlen);
|
||||
if (dirlen + pathlen + 1 > max_path - 1) {
|
||||
int abpathlen = dirlen + pathlen + 10;
|
||||
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);
|
||||
}
|
||||
pathbuf = prefixAbpath(ps, pathlen, dirlen + pathlen);
|
||||
} else {
|
||||
pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
|
||||
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…
x
Reference in New Issue
Block a user