mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-02 00:34:44 +00:00
7003155: (fs) Paths.get(<file-uri>) does not handle escaped octets correctly
Reviewed-by: sherman
This commit is contained in:
parent
bc1f07b587
commit
6207a0fa9c
@ -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(""))
|
||||
throw new IllegalArgumentException("URI path component is empty");
|
||||
if (path.endsWith("/") && (path.length() > 1)) {
|
||||
// "/foo/" --> "/foo", but "/" --> "/"
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
// compatability with java.io.File
|
||||
if (!uri.toString().startsWith("file:///"))
|
||||
return new File(uri).toPath();
|
||||
|
||||
// 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;
|
||||
// transformation use raw path
|
||||
String p = uri.getRawPath();
|
||||
int len = p.length();
|
||||
if (len == 0)
|
||||
throw new IllegalArgumentException("URI path component is empty");
|
||||
|
||||
// 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);
|
||||
failures++;
|
||||
return;
|
||||
}
|
||||
Path q = Paths.get(u);
|
||||
log.println(" --> " + q);
|
||||
if (!p.toAbsolutePath().equals(q)) {
|
||||
log.println("FAIL: Expected " + p + ", got " + q);
|
||||
failures++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void test(String fn) {
|
||||
test(fn, null);
|
||||
/**
|
||||
* 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 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++;
|
||||
}
|
||||
log.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user