8048990: ZipFile.entries() can't handle empty zip entry names
Summary: getEntryBytes should never return null pointer for entry names
Reviewed-by: sherman
--- 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();