8048990: ZipFile.entries() can't handle empty zip entry names

GetEntryBytes should never return null pointer for entry names

Reviewed-by: sherman
This commit is contained in:
Martin Buchholz 2014-07-02 10:21:23 -07:00
parent fb6a582728
commit b6e211ab64
2 changed files with 76 additions and 26 deletions

View File

@ -272,7 +272,9 @@ Java_java_util_zip_ZipFile_getEntryBytes(JNIEnv *env,
case java_util_zip_ZipFile_JZENTRY_NAME: case java_util_zip_ZipFile_JZENTRY_NAME:
if (ze->name != 0) { if (ze->name != 0) {
len = (int)strlen(ze->name); 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; break;
(*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name); (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);
} }

View File

@ -22,7 +22,7 @@
*/ */
/* @test /* @test
* @bug 4770745 6234507 6303183 * @bug 4770745 6234507 6303183 8048990
* @summary test a variety of zip file entries * @summary test a variety of zip file entries
* @author Martin Buchholz * @author Martin Buchholz
*/ */
@ -137,8 +137,11 @@ public class Assortment {
return fdata; return fdata;
} }
void verify(ZipFile f) throws Exception { void verify(ZipFile f, ZipEntry e) throws Exception {
ZipEntry e = f.getEntry(name); verify(e, getData(f, e));
}
void verify(ZipEntry e, byte[] eData) throws Exception {
byte[] data = (this.data == null) ? new byte[]{} : this.data; byte[] data = (this.data == null) ? new byte[]{} : this.data;
byte[] extra = (this.extra != null && this.extra.length == 0) ? byte[] extra = (this.extra != null && this.extra.length == 0) ?
null : this.extra; null : this.extra;
@ -148,21 +151,23 @@ public class Assortment {
&& (e.getComment() == null)) && (e.getComment() == null))
|| comment.equals(e.getComment())); || comment.equals(e.getComment()));
check(equalsExtraData(extra, e.getExtra())); check(equalsExtraData(extra, e.getExtra()));
check(Arrays.equals(data, getData(f, e))); check(Arrays.equals(data, eData));
check(e.getSize() == data.length); check(e.getSize() == data.length);
check((method == ZipEntry.DEFLATED) || check((method == ZipEntry.DEFLATED) ||
(e.getCompressedSize() == data.length)); (e.getCompressedSize() == data.length));
} }
void verify(JarInputStream jis) throws Exception { void verify(ZipFile f) throws Exception {
// JarInputStream "automatically" reads the manifest ZipEntry e = f.getEntry(name);
if (name.equals("meta-iNf/ManIfEst.Mf")) verify(e, getData(f, e));
return; }
ZipEntry e = jis.getNextEntry();
void verifyZipInputStream(ZipInputStream s) throws Exception {
ZipEntry e = s.getNextEntry();
byte[] data = (this.data == null) ? new byte[]{} : this.data; byte[] data = (this.data == null) ? new byte[]{} : this.data;
byte[] otherData = new byte[data.length]; byte[] otherData = new byte[data.length];
jis.read(otherData); s.read(otherData);
check(Arrays.equals(data, otherData)); check(Arrays.equals(data, otherData));
byte[] extra = (this.extra != null && this.extra.length == 0) ? byte[] extra = (this.extra != null && this.extra.length == 0) ?
@ -173,7 +178,14 @@ public class Assortment {
check(e.getSize() == -1 || e.getSize() == data.length); check(e.getSize() == -1 || e.getSize() == data.length);
check((method == ZipEntry.DEFLATED) || check((method == ZipEntry.DEFLATED) ||
(e.getCompressedSize() == data.length)); (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 @@ public class Assortment {
"Can manifests have comments??")); "Can manifests have comments??"));
// The emptiest possible entry // 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 (String name : names)
for (int method : methods) for (int method : methods)
@ -246,30 +258,66 @@ public class Assortment {
} }
//---------------------------------------------------------------- //----------------------------------------------------------------
// Verify zip file contents using JarFile class // Verify zip file contents using ZipFile.getEntry()
//---------------------------------------------------------------- //----------------------------------------------------------------
JarFile f = new JarFile(zipName); try (ZipFile f = new ZipFile(zipName)) {
for (Entry e : entries)
e.verify(f);
}
check(f.getManifest() != null); //----------------------------------------------------------------
// Verify zip file contents using JarFile.getEntry()
//----------------------------------------------------------------
try (JarFile f = new JarFile(zipName)) {
check(f.getManifest() != null);
for (Entry e : entries)
e.verify(f);
}
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());
f.close(); 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());
check(!en.hasMoreElements());
}
//----------------------------------------------------------------
// 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 // Verify zip file contents using JarInputStream class
//---------------------------------------------------------------- //----------------------------------------------------------------
JarInputStream jis = new JarInputStream( try (FileInputStream fis = new FileInputStream(zipName);
new FileInputStream(zipName)); JarInputStream s = new JarInputStream(fis)) {
// JarInputStream "automatically" reads the manifest // JarInputStream "automatically" reads the manifest
check(jis.getManifest() != null); check(s.getManifest() != null);
for (Entry e : entries) for (Entry e : entries)
e.verify(jis); e.verifyJarInputStream(s);
}
jis.close();
// String cmd = "unzip -t " + zipName.getPath() + " >/dev/tty"; // String cmd = "unzip -t " + zipName.getPath() + " >/dev/tty";
// new ProcessBuilder(new String[]{"/bin/sh", "-c", cmd}).start().waitFor(); // new ProcessBuilder(new String[]{"/bin/sh", "-c", cmd}).start().waitFor();