6233323: ZipEntry.isDirectory() may return false incorrectly

8144977: Class.getResourceAsStream("directory") in JAR returns broken InputStream

Reviewed-by: rriggs
This commit is contained in:
Xueming Shen 2016-06-28 15:36:15 -07:00
parent ed73972cda
commit c19f3e0db2
2 changed files with 45 additions and 7 deletions
jdk
src/java.base/share/classes/java/util/zip
test/java/util/zip/ZipFile

@ -295,13 +295,13 @@ class ZipFile implements ZipConstants, Closeable {
* @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 @@ class ZipFile implements ZipConstants, Closeable {
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 @@ class ZipFile implements ZipConstants, Closeable {
}
/* 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 {

@ -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 @@ public class ReadZip {
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", "."),