From c19f3e0db256aeafca34017e6322f022d1e14e45 Mon Sep 17 00:00:00 2001 From: Xueming Shen Date: Tue, 28 Jun 2016 15:36:15 -0700 Subject: [PATCH] 6233323: ZipEntry.isDirectory() may return false incorrectly 8144977: Class.getResourceAsStream("directory") in JAR returns broken InputStream Reviewed-by: rriggs --- .../share/classes/java/util/zip/ZipFile.java | 16 +++++---- jdk/test/java/util/zip/ZipFile/ReadZip.java | 36 ++++++++++++++++++- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java index cc9153608e2..ef26d1784cc 100644 --- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -295,13 +295,13 @@ class ZipFile implements ZipConstants, Closeable { * @throws IllegalStateException if the zip file has been closed */ public ZipEntry getEntry(String name) { - Objects.requireNonNull(name, "name"); synchronized (this) { ensureOpen(); - int pos = zsrc.getEntryPos(zc.getBytes(name), true); + byte[] bname = zc.getBytes(name); + int pos = zsrc.getEntryPos(bname, true); if (pos != -1) { - return getZipEntry(name, pos); + return getZipEntry(name, bname, pos); } } return null; @@ -492,7 +492,7 @@ class ZipFile implements ZipConstants, Closeable { throw new NoSuchElementException(); } // each "entry" has 3 ints in table entries - return getZipEntry(null, zsrc.getEntryPos(i++ * 3)); + return getZipEntry(null, null, zsrc.getEntryPos(i++ * 3)); } } @@ -527,13 +527,17 @@ class ZipFile implements ZipConstants, Closeable { } /* Checks ensureOpen() before invoke this method */ - private ZipEntry getZipEntry(String name, int pos) { + private ZipEntry getZipEntry(String name, byte[] bname, int pos) { byte[] cen = zsrc.cen; int nlen = CENNAM(cen, pos); int elen = CENEXT(cen, pos); int clen = CENCOM(cen, pos); int flag = CENFLG(cen, pos); - if (name == null) { + if (name == null || bname.length != nlen) { + // to use the entry name stored in cen, if the passed in name is + // (1) null, invoked from iterator, or + // (2) not equal to the name stored, a slash is appended during + // getEntryPos() search. if (!zc.isUTF8() && (flag & EFS) != 0) { name = zc.toStringUTF8(cen, pos + CENHDR, nlen); } else { diff --git a/jdk/test/java/util/zip/ZipFile/ReadZip.java b/jdk/test/java/util/zip/ZipFile/ReadZip.java index fe923e81eee..465f1ce3731 100644 --- a/jdk/test/java/util/zip/ZipFile/ReadZip.java +++ b/jdk/test/java/util/zip/ZipFile/ReadZip.java @@ -22,7 +22,7 @@ */ /* @test - @bug 4241361 4842702 4985614 6646605 5032358 6923692 + @bug 4241361 4842702 4985614 6646605 5032358 6923692 6233323 8144977 @summary Make sure we can read a zip file. @key randomness */ @@ -105,6 +105,40 @@ public class ReadZip { newZip.delete(); } + // Read directory entry + try { + try (FileOutputStream fos = new FileOutputStream(newZip); + ZipOutputStream zos = new ZipOutputStream(fos)) + { + ZipEntry ze = new ZipEntry("directory/"); + zos.putNextEntry(ze); + zos.closeEntry(); + } + try (ZipFile zf = new ZipFile(newZip)) { + ZipEntry ze = zf.getEntry("directory/"); + if (ze == null || !ze.isDirectory()) + throw new RuntimeException("read entry \"directory/\" failed"); + try (InputStream is = zf.getInputStream(ze)) { + is.available(); + } catch (Exception x) { + x.printStackTrace(); + } + + ze = zf.getEntry("directory"); + if (ze == null || !ze.isDirectory()) + throw new RuntimeException("read entry \"directory\" failed"); + try (InputStream is = zf.getInputStream(ze)) { + is.available(); + } catch (Exception x) { + x.printStackTrace(); + } + } + } finally { + newZip.delete(); + } + + + // Throw a FNF exception when read a non-existing zip file try { unreached (new ZipFile( new File(System.getProperty("test.src", "."),