提交 5f9cb587 编写于 作者: A alanb

7003155: (fs) Paths.get(<file-uri>) does not handle escaped octets correctly

Reviewed-by: sherman
上级 6bce28ac
...@@ -25,8 +25,11 @@ ...@@ -25,8 +25,11 @@
package sun.nio.fs; package sun.nio.fs;
import java.nio.file.Path;
import java.io.File;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Arrays;
/** /**
* Unix specific Path <--> URI conversion * Unix specific Path <--> URI conversion
...@@ -38,7 +41,7 @@ class UnixUriUtils { ...@@ -38,7 +41,7 @@ class UnixUriUtils {
/** /**
* Converts URI to Path * Converts URI to Path
*/ */
static UnixPath fromUri(UnixFileSystem fs, URI uri) { static Path fromUri(UnixFileSystem fs, URI uri) {
if (!uri.isAbsolute()) if (!uri.isAbsolute())
throw new IllegalArgumentException("URI is not absolute"); throw new IllegalArgumentException("URI is not absolute");
if (uri.isOpaque()) if (uri.isOpaque())
...@@ -53,22 +56,41 @@ class UnixUriUtils { ...@@ -53,22 +56,41 @@ class UnixUriUtils {
if (uri.getQuery() != null) if (uri.getQuery() != null)
throw new IllegalArgumentException("URI has a query component"); throw new IllegalArgumentException("URI has a query component");
String path = uri.getPath(); // compatability with java.io.File
if (path.equals("")) if (!uri.toString().startsWith("file:///"))
return new File(uri).toPath();
// transformation use raw path
String p = uri.getRawPath();
int len = p.length();
if (len == 0)
throw new IllegalArgumentException("URI path component is empty"); throw new IllegalArgumentException("URI path component is empty");
if (path.endsWith("/") && (path.length() > 1)) {
// "/foo/" --> "/foo", but "/" --> "/"
path = path.substring(0, path.length() - 1);
}
// preserve bytes // transform escaped octets and unescaped characters to bytes
byte[] result = new byte[path.length()]; if (p.endsWith("/") && len > 1)
for (int i=0; i<path.length(); i++) { len--;
byte v = (byte)(path.charAt(i)); byte[] result = new byte[len];
if (v == 0) int rlen = 0;
int pos = 0;
while (pos < len) {
char c = p.charAt(pos++);
byte b;
if (c == '%') {
assert (pos+2) <= len;
char c1 = p.charAt(pos++);
char c2 = p.charAt(pos++);
b = (byte)((decode(c1) << 4) | decode(c2));
if (b == 0)
throw new IllegalArgumentException("Nul character not allowed"); throw new IllegalArgumentException("Nul character not allowed");
result[i] = v; } else {
assert c < 0x80;
b = (byte)c;
}
result[rlen++] = b;
} }
if (rlen != result.length)
result = Arrays.copyOf(result, rlen);
return new UnixPath(fs, result); return new UnixPath(fs, result);
} }
...@@ -86,7 +108,7 @@ class UnixUriUtils { ...@@ -86,7 +108,7 @@ class UnixUriUtils {
} else { } else {
sb.append('%'); sb.append('%');
sb.append(hexDigits[(c >> 4) & 0x0f]); sb.append(hexDigits[(c >> 4) & 0x0f]);
sb.append(hexDigits[(c >> 0) & 0x0f]); sb.append(hexDigits[(c) & 0x0f]);
} }
} }
...@@ -164,6 +186,17 @@ class UnixUriUtils { ...@@ -164,6 +186,17 @@ class UnixUriUtils {
return false; return false;
} }
// decode
private static int decode(char c) {
if ((c >= '0') && (c <= '9'))
return c - '0';
if ((c >= 'a') && (c <= 'f'))
return c - 'a' + 10;
if ((c >= 'A') && (c <= 'F'))
return c - 'A' + 10;
throw new AssertionError();
}
// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | // digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
// "8" | "9" // "8" | "9"
private static final long L_DIGIT = lowMask('0', '9'); private static final long L_DIGIT = lowMask('0', '9');
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
*/ */
/* @test /* @test
* @bug 4313887 * @bug 4313887 7003155
* @summary Unit test for java.nio.file.Path * @summary Unit test for java.nio.file.Path
*/ */
...@@ -36,42 +36,105 @@ public class UriImportExport { ...@@ -36,42 +36,105 @@ public class UriImportExport {
static final PrintStream log = System.out; static final PrintStream log = System.out;
static int failures = 0; static int failures = 0;
static void test(String fn, String expected) { /**
* Test Path -> URI -> Path
*/
static void testPath(String s) {
Path path = Paths.get(s);
log.println(path);
URI uri = path.toUri();
log.println(" --> " + uri);
Path result = Paths.get(uri);
log.println(" --> " + result);
if (!result.equals(path.toAbsolutePath())) {
log.println("FAIL: Expected " + path + ", got " + result);
failures++;
}
log.println(); log.println();
Path p = Paths.get(fn); }
log.println(p);
URI u = p.toUri(); /**
log.println(" --> " + u); * Test Path -> (expected) URI -> Path
if (expected != null && !(u.toString().equals(expected))) { */
log.println("FAIL: Expected " + expected); static void testPath(String s, String expectedUri) {
Path path = Paths.get(s);
log.println(path);
URI uri = path.toUri();
log.println(" --> " + uri);
if (!uri.toString().equals(expectedUri)) {
log.println("FAILED: Expected " + expectedUri + ", got " + uri);
failures++; failures++;
return; return;
} }
Path q = Paths.get(u); Path result = Paths.get(uri);
log.println(" --> " + q); log.println(" --> " + result);
if (!p.toAbsolutePath().equals(q)) { if (!result.equals(path.toAbsolutePath())) {
log.println("FAIL: Expected " + p + ", got " + q); log.println("FAIL: Expected " + path + ", got " + result);
failures++;
}
log.println();
}
/**
* Test URI -> Path -> URI
*/
static void testUri(String s) throws Exception {
URI uri = URI.create(s);
log.println(uri);
Path path = Paths.get(uri);
log.println(" --> " + path);
URI result = path.toUri();
log.println(" --> " + result);
if (!result.equals(uri)) {
log.println("FAIL: Expected " + uri + ", got " + result);
failures++; failures++;
return;
} }
log.println();
} }
static void test(String fn) { /**
test(fn, null); * Test URI -> Path fails with IllegalArgumentException
*/
static void testBadUri(String s) throws Exception {
URI uri = URI.create(s);
log.println(uri);
try {
Path path = Paths.get(uri);
log.format(" --> %s FAIL: Expected IllegalArgumentException\n", path);
failures++;
} catch (IllegalArgumentException expected) {
log.println(" --> IllegalArgumentException (expected)");
}
log.println();
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
test("foo"); testBadUri("file:foo");
test("/foo"); testBadUri("file:/foo?q");
test("/foo bar"); testBadUri("file:/foo#f");
String osname = System.getProperty("os.name"); String osname = System.getProperty("os.name");
if (osname.startsWith("Windows")) { if (osname.startsWith("Windows")) {
test("C:\\foo"); testPath("C:\\doesnotexist");
test("C:foo"); testPath("C:doesnotexist");
test("\\\\rialto.dublin.com\\share\\"); testPath("\\\\server.nowhere.oracle.com\\share\\");
test("\\\\fe80--203-baff-fe5a-749ds1.ipv6-literal.net\\share\\missing", testPath("\\\\fe80--203-baff-fe5a-749ds1.ipv6-literal.net\\share\\missing",
"file://[fe80::203:baff:fe5a:749d%1]/share/missing"); "file://[fe80::203:baff:fe5a:749d%1]/share/missing");
} else {
testPath("doesnotexist");
testPath("/doesnotexist");
testPath("/does not exist");
testUri("file:///");
testUri("file:///foo/bar/doesnotexist");
testUri("file:/foo/bar/doesnotexist");
// file:///foo/bar/\u0440\u0443\u0441\u0441\u043A\u0438\u0439 (Russian)
testUri("file:///foo/bar/%D1%80%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9");
// invalid
testBadUri("file:foo");
testBadUri("file://server/foo");
testBadUri("file:///foo%00");
} }
if (failures > 0) if (failures > 0)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册