# HG changeset patch # User martin # Date 1404321683 25200 # Node ID 5d63cd3696d6e73320616a3d703d0261b6fad2aa # Parent 0fa04dba779ca834584ea318db5444ed577c0252 8048990: ZipFile.entries() can't handle empty zip entry names Summary: getEntryBytes should never return null pointer for entry names Reviewed-by: sherman diff -r 0fa04dba779c -r 5d63cd3696d6 jdk/src/share/native/java/util/zip/ZipFile.c --- 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); } diff -r 0fa04dba779c -r 5d63cd3696d6 jdk/test/java/util/zip/ZipFile/Assortment.java --- 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 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 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();