提交 09296ee2 编写于 作者: S sherman

6481955: Uncanonicalized absolute filepath with length 248-260 no longer works (win)

Summary: Uncanonicalized absolute filepath with length 248-260 no longer works (win)
Reviewed-by: alanb
上级 98733aaa
......@@ -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) {
......
/*
* 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;
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册