8339711: ZipFile.Source.initCEN needlessly reads END header

Reviewed-by: lancea, jpai, redestad
This commit is contained in:
Eirik Bjørsnøs 2024-09-30 13:06:49 +00:00
parent 180affc571
commit cff420d8d3
3 changed files with 19 additions and 12 deletions

View file

@ -63,6 +63,7 @@ import java.util.stream.StreamSupport;
import jdk.internal.access.JavaUtilZipFileAccess;
import jdk.internal.access.JavaUtilJarAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.util.ArraysSupport;
import jdk.internal.util.OperatingSystem;
import jdk.internal.perf.PerfCounter;
import jdk.internal.ref.CleanerFactory;
@ -1178,6 +1179,8 @@ public class ZipFile implements ZipConstants, Closeable {
// "META-INF/".length()
private static final int META_INF_LEN = 9;
private static final int[] EMPTY_META_VERSIONS = new int[0];
// CEN size is limited to the maximum array size in the JDK
private static final int MAX_CEN_SIZE = ArraysSupport.SOFT_MAX_ARRAY_LENGTH;
private final Key key; // the key in files
private final @Stable ZipCoder zc; // ZIP coder used to decode/encode
@ -1185,7 +1188,7 @@ public class ZipFile implements ZipConstants, Closeable {
private int refs = 1;
private RandomAccessFile zfile; // zfile of the underlying ZIP file
private byte[] cen; // CEN & ENDHDR
private byte[] cen; // CEN
private long locpos; // position of first LOC header (usually 0)
private byte[] comment; // ZIP file comment
// list of meta entries in META-INF dir
@ -1241,7 +1244,7 @@ public class ZipFile implements ZipConstants, Closeable {
// should not exceed 65,535 bytes per the PKWare APP.NOTE
// 4.4.10, 4.4.11, & 4.4.12. Also check that current CEN header will
// not exceed the length of the CEN array
if (headerSize > 0xFFFF || pos + headerSize > cen.length - ENDHDR) {
if (headerSize > 0xFFFF || pos + headerSize > cen.length) {
zerror("invalid CEN header (bad header size)");
}
@ -1294,7 +1297,7 @@ public class ZipFile implements ZipConstants, Closeable {
}
// CEN Offset where this Extra field ends
int extraEndOffset = startingOffset + extraFieldLen;
if (extraEndOffset > cen.length - ENDHDR) {
if (extraEndOffset > cen.length) {
zerror("Invalid CEN header (extra data field size too long)");
}
int currentOffset = startingOffset;
@ -1732,12 +1735,12 @@ public class ZipFile implements ZipConstants, Closeable {
if (locpos < 0) {
zerror("invalid END header (bad central directory offset)");
}
// read in the CEN and END
if (end.cenlen + ENDHDR >= Integer.MAX_VALUE) {
// read in the CEN
if (end.cenlen > MAX_CEN_SIZE) {
zerror("invalid END header (central directory size too large)");
}
cen = this.cen = new byte[(int)(end.cenlen + ENDHDR)];
if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) {
cen = this.cen = new byte[(int)end.cenlen];
if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen) {
zerror("read CEN tables failed");
}
this.total = end.centot;
@ -1766,7 +1769,7 @@ public class ZipFile implements ZipConstants, Closeable {
int idx = 0; // Index into the entries array
int pos = 0;
int entryPos = CENHDR;
int limit = cen.length - ENDHDR;
int limit = cen.length;
manifestNum = 0;
while (entryPos <= limit) {
if (idx >= entriesLength) {
@ -1829,7 +1832,7 @@ public class ZipFile implements ZipConstants, Closeable {
} else {
metaVersions = EMPTY_META_VERSIONS;
}
if (pos + ENDHDR != cen.length) {
if (pos != cen.length) {
zerror("invalid CEN header (bad header size)");
}
}