# HG changeset patch # User sherman # Date 1464799928 25200 # Node ID 8046caf79f1c3680136888c146d371abcdb04983 # Parent 7d6930523e385a07aca866588ffaa24343f63a3d 8061777: (zipfs) IllegalArgumentException in ZipCoder.toString when using Shitft_JIS Reviewed-by: psandoz diff -r 7d6930523e38 -r 8046caf79f1c jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java --- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Wed Jun 01 14:33:44 2016 +0100 +++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Wed Jun 01 09:52:08 2016 -0700 @@ -69,7 +69,7 @@ private final ZipFileSystemProvider provider; private final Path zfpath; - private final ZipCoder zc; + final ZipCoder zc; private final boolean noExtt; // see readExtra() private final ZipPath rootdir; // configurable by env map @@ -163,7 +163,7 @@ @Override public ZipPath getPath(String first, String... more) { if (more.length == 0) { - return new ZipPath(this, getBytes(first)); + return new ZipPath(this, first); } StringBuilder sb = new StringBuilder(); sb.append(first); @@ -175,7 +175,7 @@ sb.append(path); } } - return new ZipPath(this, getBytes(sb.toString())); + return new ZipPath(this, sb.toString()); } @Override diff -r 7d6930523e38 -r 8046caf79f1c jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java --- a/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java Wed Jun 01 14:33:44 2016 +0100 +++ b/jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java Wed Jun 01 09:52:08 2016 -0700 @@ -52,13 +52,28 @@ this(zfs, path, false); } - ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized) - { + ZipPath(ZipFileSystem zfs, byte[] path, boolean normalized) { this.zfs = zfs; - if (normalized) + if (normalized) { this.path = path; - else + } else { + if (zfs.zc.isUTF8()) { + this.path = normalize(path); + } else { + // see normalize(String); + this.path = normalize(zfs.getString(path)); + } + } + } + + ZipPath(ZipFileSystem zfs, String path) { + this.zfs = zfs; + if (zfs.zc.isUTF8()) { + this.path = normalize(zfs.getBytes(path)); + } else { + // see normalize(String); this.path = normalize(path); + } } @Override @@ -471,6 +486,50 @@ return (m == to.length)? to : Arrays.copyOf(to, m); } + // if zfs is NOT in utf8, normalize the path as "String" + // to avoid incorrectly normalizing byte '0x5c' (as '\') + // to '/'. + private byte[] normalize(String path) { + int len = path.length(); + if (len == 0) + return new byte[0]; + char prevC = 0; + for (int i = 0; i < len; i++) { + char c = path.charAt(i); + if (c == '\\' || c == '\u0000') + return normalize(path, i, len); + if (c == '/' && prevC == '/') + return normalize(path, i - 1, len); + prevC = c; + } + if (len > 1 && prevC == '/') + path = path.substring(0, len - 1); + return zfs.getBytes(path); + } + + private byte[] normalize(String path, int off, int len) { + StringBuilder to = new StringBuilder(len); + to.append(path, 0, off); + int m = off; + char prevC = 0; + while (off < len) { + char c = path.charAt(off++); + if (c == '\\') + c = '/'; + if (c == '/' && prevC == '/') + continue; + if (c == '\u0000') + throw new InvalidPathException(path, + "Path: nul character not allowed"); + to.append(c); + prevC = c; + } + len = to.length(); + if (len > 1 && prevC == '/') + to.delete(len -1, len); + return zfs.getBytes(to.toString()); + } + // Remove DotSlash(./) and resolve DotDot (..) components private byte[] getResolved() { for (int i = 0; i < path.length; i++) { diff -r 7d6930523e38 -r 8046caf79f1c jdk/test/jdk/nio/zipfs/ZFSTests.java --- a/jdk/test/jdk/nio/zipfs/ZFSTests.java Wed Jun 01 14:33:44 2016 +0100 +++ b/jdk/test/jdk/nio/zipfs/ZFSTests.java Wed Jun 01 09:52:08 2016 -0700 @@ -22,7 +22,7 @@ */ /* @test - * @bug 7156873 8040059 8028480 8034773 8153248 + * @bug 7156873 8040059 8028480 8034773 8153248 8061777 * @summary ZipFileSystem regression tests * * @run main ZFSTests @@ -43,6 +43,7 @@ public static void main(String[] args) throws Throwable { test7156873(); + test8061777(); tests(); } @@ -62,6 +63,34 @@ } } + static void test8061777() throws Throwable { + Path path = Paths.get("file.zip"); + try { + URI uri = URI.create("jar:" + path.toUri()); + Map env = new HashMap(); + env.put("create", "true"); + env.put("encoding", "Shift_JIS"); + try (FileSystem fs = FileSystems.newFileSystem(uri, env)) { + FileSystemProvider fsp = fs.provider(); + Path p = fs.getPath("/\u8868\u7533.txt"); // 0x95 0x5c 0x90 0x5c + try (OutputStream os = fsp.newOutputStream(p)) { + os.write("Hello!".getBytes("ASCII")); + } + Path dir = fs.getPath("/"); + Files.list(dir) + .forEach( child -> { + System.out.println("child:" + child); + if (!child.toString().equals(p.toString())) + throw new RuntimeException("wrong path name created"); + }); + if (!"Hello!".equals(new String(Files.readAllBytes(p), "ASCII"))) + throw new RuntimeException("wrong content in newly created file"); + } + } finally { + Files.deleteIfExists(path); + } + } + static void tests() throws Throwable { Path path = Paths.get("file.zip"); try {