8048990: ZipFile.entries() can't handle empty zip entry names
authormartin
Wed, 02 Jul 2014 10:21:23 -0700
changeset 25222 5d63cd3696d6
parent 25221 0fa04dba779c
child 25223 4d33af5975a5
8048990: ZipFile.entries() can't handle empty zip entry names Summary: getEntryBytes should never return null pointer for entry names Reviewed-by: sherman
jdk/src/share/native/java/util/zip/ZipFile.c
jdk/test/java/util/zip/ZipFile/Assortment.java
--- a/jdk/src/share/native/java/util/zip/ZipFile.c	Wed Jul 02 10:03:40 2014 +0100
+++ b/jdk/src/share/native/java/util/zip/ZipFile.c	Wed Jul 02 10:21:23 2014 -0700
@@ -272,7 +272,9 @@
     case java_util_zip_ZipFile_JZENTRY_NAME:
         if (ze->name != 0) {
             len = (int)strlen(ze->name);
-            if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
+            // Unlike for extra and comment, we never return null for
+            // an (extremely rarely seen) empty name
+            if ((jba = (*env)->NewByteArray(env, len)) == NULL)
                 break;
             (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);
         }
--- a/jdk/test/java/util/zip/ZipFile/Assortment.java	Wed Jul 02 10:03:40 2014 +0100
+++ b/jdk/test/java/util/zip/ZipFile/Assortment.java	Wed Jul 02 10:21:23 2014 -0700
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 4770745 6234507 6303183
+ * @bug 4770745 6234507 6303183 8048990
  * @summary test a variety of zip file entries
  * @author Martin Buchholz
  */
@@ -137,8 +137,11 @@
             return fdata;
         }
 
-        void verify(ZipFile f) throws Exception {
-            ZipEntry e = f.getEntry(name);
+        void verify(ZipFile f, ZipEntry e) throws Exception {
+            verify(e, getData(f, e));
+        }
+
+        void verify(ZipEntry e, byte[] eData) throws Exception {
             byte[] data  = (this.data == null) ? new byte[]{} : this.data;
             byte[] extra = (this.extra != null && this.extra.length == 0) ?
                 null : this.extra;
@@ -148,21 +151,23 @@
                    && (e.getComment() == null))
                   || comment.equals(e.getComment()));
             check(equalsExtraData(extra, e.getExtra()));
-            check(Arrays.equals(data, getData(f, e)));
+            check(Arrays.equals(data, eData));
             check(e.getSize() == data.length);
             check((method == ZipEntry.DEFLATED) ||
                   (e.getCompressedSize() == data.length));
         }
 
-        void verify(JarInputStream jis) throws Exception {
-            // JarInputStream "automatically" reads the manifest
-            if (name.equals("meta-iNf/ManIfEst.Mf"))
-                return;
-            ZipEntry e = jis.getNextEntry();
+        void verify(ZipFile f) throws Exception {
+            ZipEntry e = f.getEntry(name);
+            verify(e, getData(f, e));
+        }
+
+        void verifyZipInputStream(ZipInputStream s) throws Exception {
+            ZipEntry e = s.getNextEntry();
 
             byte[] data = (this.data == null) ? new byte[]{} : this.data;
             byte[] otherData = new byte[data.length];
-            jis.read(otherData);
+            s.read(otherData);
             check(Arrays.equals(data, otherData));
 
             byte[] extra = (this.extra != null && this.extra.length == 0) ?
@@ -173,7 +178,14 @@
             check(e.getSize() == -1 || e.getSize() == data.length);
             check((method == ZipEntry.DEFLATED) ||
                   (e.getCompressedSize() == data.length));
+        }
 
+        void verifyJarInputStream(JarInputStream s) throws Exception {
+            // JarInputStream "automatically" reads the manifest
+            if (name.equals("meta-iNf/ManIfEst.Mf"))
+                return;
+
+            verifyZipInputStream(s);
         }
     }
 
@@ -225,7 +237,7 @@
                               "Can manifests have comments??"));
 
         // The emptiest possible entry
-        entries.add(new Entry("", ZipEntry.STORED,   null, null, ""));
+        entries.add(new Entry("", ZipEntry.STORED, null, null, ""));
 
         for (String name : names)
             for (int method : methods)
@@ -246,30 +258,66 @@
         }
 
         //----------------------------------------------------------------
-        // Verify zip file contents using JarFile class
+        // Verify zip file contents using ZipFile.getEntry()
+        //----------------------------------------------------------------
+        try (ZipFile f = new ZipFile(zipName)) {
+            for (Entry e : entries)
+                e.verify(f);
+        }
+
+        //----------------------------------------------------------------
+        // Verify zip file contents using JarFile.getEntry()
         //----------------------------------------------------------------
-        JarFile f = new JarFile(zipName);
+        try (JarFile f = new JarFile(zipName)) {
+            check(f.getManifest() != null);
+            for (Entry e : entries)
+                e.verify(f);
+        }
+
+        //----------------------------------------------------------------
+        // Verify zip file contents using ZipFile.entries()
+        //----------------------------------------------------------------
+        try (ZipFile f = new ZipFile(zipName)) {
+            Enumeration<? extends ZipEntry> en = f.entries();
+            for (Entry e : entries)
+                e.verify(f, en.nextElement());
 
-        check(f.getManifest() != null);
+            check(!en.hasMoreElements());
+        }
+
+        //----------------------------------------------------------------
+        // Verify zip file contents using JarFile.entries()
+        //----------------------------------------------------------------
+        try (JarFile f = new JarFile(zipName)) {
+            Enumeration<? extends ZipEntry> en = f.entries();
+            for (Entry e : entries)
+                e.verify(f, en.nextElement());
 
-        for (Entry e : entries)
-            e.verify(f);
+            check(!en.hasMoreElements());
+        }
 
-        f.close();
+        //----------------------------------------------------------------
+        // Verify zip file contents using ZipInputStream class
+        //----------------------------------------------------------------
+        try (FileInputStream fis = new FileInputStream(zipName);
+             ZipInputStream s = new ZipInputStream(fis)) {
+
+            for (Entry e : entries)
+                e.verifyZipInputStream(s);
+        }
 
         //----------------------------------------------------------------
         // Verify zip file contents using JarInputStream class
         //----------------------------------------------------------------
-        JarInputStream jis = new JarInputStream(
-            new FileInputStream(zipName));
+        try (FileInputStream fis = new FileInputStream(zipName);
+             JarInputStream s = new JarInputStream(fis)) {
 
-        // JarInputStream "automatically" reads the manifest
-        check(jis.getManifest() != null);
+            // JarInputStream "automatically" reads the manifest
+            check(s.getManifest() != null);
 
-        for (Entry e : entries)
-            e.verify(jis);
-
-        jis.close();
+            for (Entry e : entries)
+                e.verifyJarInputStream(s);
+        }
 
 //      String cmd = "unzip -t " + zipName.getPath() + " >/dev/tty";
 //      new ProcessBuilder(new String[]{"/bin/sh", "-c", cmd}).start().waitFor();