6233323: ZipEntry.isDirectory() may return false incorrectly
authorsherman
Tue, 28 Jun 2016 15:36:15 -0700
changeset 39310 fed59f4021c8
parent 39309 1a3bcf3d6034
child 39311 3f2a464afd5e
6233323: ZipEntry.isDirectory() may return false incorrectly 8144977: Class.getResourceAsStream("directory") in JAR returns broken InputStream Reviewed-by: rriggs
jdk/src/java.base/share/classes/java/util/zip/ZipFile.java
jdk/test/java/util/zip/ZipFile/ReadZip.java
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java	Tue Jun 28 20:03:29 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java	Tue Jun 28 15:36:15 2016 -0700
@@ -295,13 +295,13 @@
      * @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 @@
                     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 @@
     }
 
     /* 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 {
--- a/jdk/test/java/util/zip/ZipFile/ReadZip.java	Tue Jun 28 20:03:29 2016 +0100
+++ b/jdk/test/java/util/zip/ZipFile/ReadZip.java	Tue Jun 28 15:36:15 2016 -0700
@@ -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 @@
             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", "."),