提交 2aae5ac1 编写于 作者: T tbell

Merge

...@@ -188,21 +188,22 @@ import sun.security.action.GetPropertyAction; ...@@ -188,21 +188,22 @@ import sun.security.action.GetPropertyAction;
* <ul> * <ul>
* *
* <li><p> When decoding, the <tt>UTF-16BE</tt> and <tt>UTF-16LE</tt> * <li><p> When decoding, the <tt>UTF-16BE</tt> and <tt>UTF-16LE</tt>
* charsets ignore byte-order marks; when encoding, they do not write * charsets interpret the initial byte-order marks as a <small>ZERO-WIDTH
* NON-BREAKING SPACE</small>; when encoding, they do not write
* byte-order marks. </p></li> * byte-order marks. </p></li>
* *
* <li><p> When decoding, the <tt>UTF-16</tt> charset interprets a byte-order * <li><p> When decoding, the <tt>UTF-16</tt> charset interprets the
* mark to indicate the byte order of the stream but defaults to big-endian * byte-order mark at the beginning of the input stream to indicate the
* if there is no byte-order mark; when encoding, it uses big-endian byte * byte-order of the stream but defaults to big-endian if there is no
* order and writes a big-endian byte-order mark. </p></li> * byte-order mark; when encoding, it uses big-endian byte order and writes
* a big-endian byte-order mark. </p></li>
* *
* </ul> * </ul>
* *
* In any case, when a byte-order mark is read at the beginning of a decoding * In any case, byte order marks occuring after the first element of an
* operation it is omitted from the resulting sequence of characters. Byte * input sequence are not omitted since the same code is used to represent
* order marks occuring after the first element of an input sequence are not * <small>ZERO-WIDTH NON-BREAKING SPACE</small>.
* omitted since the same code is used to represent <small>ZERO-WIDTH
* NON-BREAKING SPACE</small>.
* *
* <p> Every instance of the Java virtual machine has a default charset, which * <p> Every instance of the Java virtual machine has a default charset, which
* may or may not be one of the standard charsets. The default charset is * may or may not be one of the standard charsets. The default charset is
......
...@@ -104,23 +104,56 @@ currentDirLength(const WCHAR* ps, int pathlen) { ...@@ -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) { ...@@ -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) { ...@@ -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) {
......
/*
* 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.
先完成此消息的编辑!
想要评论请 注册