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

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

Reviewed-by: sherman
上级 6bce28ac
......@@ -25,8 +25,11 @@
package sun.nio.fs;
import java.nio.file.Path;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
/**
* Unix specific Path <--> URI conversion
......@@ -38,7 +41,7 @@ class UnixUriUtils {
/**
* Converts URI to Path
*/
static UnixPath fromUri(UnixFileSystem fs, URI uri) {
static Path fromUri(UnixFileSystem fs, URI uri) {
if (!uri.isAbsolute())
throw new IllegalArgumentException("URI is not absolute");
if (uri.isOpaque())
......@@ -53,22 +56,41 @@ class UnixUriUtils {
if (uri.getQuery() != null)
throw new IllegalArgumentException("URI has a query component");
String path = uri.getPath();
if (path.equals(""))
// compatability with java.io.File
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");
if (path.endsWith("/") && (path.length() > 1)) {
// "/foo/" --> "/foo", but "/" --> "/"
path = path.substring(0, path.length() - 1);
}
// preserve bytes
byte[] result = new byte[path.length()];
for (int i=0; i<path.length(); i++) {
byte v = (byte)(path.charAt(i));
if (v == 0)
throw new IllegalArgumentException("Nul character not allowed");
result[i] = v;
// transform escaped octets and unescaped characters to bytes
if (p.endsWith("/") && len > 1)
len--;
byte[] result = new byte[len];
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");
} else {
assert c < 0x80;
b = (byte)c;
}
result[rlen++] = b;
}
if (rlen != result.length)
result = Arrays.copyOf(result, rlen);
return new UnixPath(fs, result);
}
......@@ -86,7 +108,7 @@ class UnixUriUtils {
} else {
sb.append('%');
sb.append(hexDigits[(c >> 4) & 0x0f]);
sb.append(hexDigits[(c >> 0) & 0x0f]);
sb.append(hexDigits[(c) & 0x0f]);
}
}
......@@ -164,6 +186,17 @@ class UnixUriUtils {
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" |
// "8" | "9"
private static final long L_DIGIT = lowMask('0', '9');
......
......@@ -22,7 +22,7 @@
*/
/* @test
* @bug 4313887
* @bug 4313887 7003155
* @summary Unit test for java.nio.file.Path
*/
......@@ -36,42 +36,105 @@ public class UriImportExport {
static final PrintStream log = System.out;
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();
Path p = Paths.get(fn);
log.println(p);
URI u = p.toUri();
log.println(" --> " + u);
if (expected != null && !(u.toString().equals(expected))) {
log.println("FAIL: Expected " + expected);
}
/**
* Test Path -> (expected) URI -> Path
*/
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++;
return;
}
Path q = Paths.get(u);
log.println(" --> " + q);
if (!p.toAbsolutePath().equals(q)) {
log.println("FAIL: Expected " + p + ", got " + q);
Path result = Paths.get(uri);
log.println(" --> " + result);
if (!result.equals(path.toAbsolutePath())) {
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++;
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 {
test("foo");
test("/foo");
test("/foo bar");
testBadUri("file:foo");
testBadUri("file:/foo?q");
testBadUri("file:/foo#f");
String osname = System.getProperty("os.name");
if (osname.startsWith("Windows")) {
test("C:\\foo");
test("C:foo");
test("\\\\rialto.dublin.com\\share\\");
test("\\\\fe80--203-baff-fe5a-749ds1.ipv6-literal.net\\share\\missing",
testPath("C:\\doesnotexist");
testPath("C:doesnotexist");
testPath("\\\\server.nowhere.oracle.com\\share\\");
testPath("\\\\fe80--203-baff-fe5a-749ds1.ipv6-literal.net\\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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册