8339711: ZipFile.Source.initCEN needlessly reads END header
Reviewed-by: lancea, jpai, redestad
This commit is contained in:
parent
180affc571
commit
cff420d8d3
@ -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)");
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +23,12 @@
|
||||
|
||||
/* @test
|
||||
* @bug 8272746
|
||||
* @modules java.base/jdk.internal.util
|
||||
* @summary Verify that ZipFile rejects a ZIP with a CEN size which does not fit in a Java byte array
|
||||
* @run junit CenSizeTooLarge
|
||||
*/
|
||||
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -49,7 +51,7 @@ public class CenSizeTooLarge {
|
||||
public static final int NAME_LENGTH = 10;
|
||||
|
||||
// Maximum allowed CEN size allowed by the ZipFile implementation
|
||||
static final int MAX_CEN_SIZE = Integer.MAX_VALUE - ZipFile.ENDHDR - 1;
|
||||
static final int MAX_CEN_SIZE = ArraysSupport.SOFT_MAX_ARRAY_LENGTH;
|
||||
|
||||
/**
|
||||
* From the APPNOTE.txt specification:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,10 +23,12 @@
|
||||
|
||||
/* @test
|
||||
* @bug 8272746
|
||||
* @modules java.base/jdk.internal.util
|
||||
* @summary Verify that ZipFile rejects files with CEN sizes exceeding the implementation limit
|
||||
* @run testng/othervm EndOfCenValidation
|
||||
*/
|
||||
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
@ -68,7 +70,7 @@ public class EndOfCenValidation {
|
||||
private static final int ENDSIZ = ZipFile.ENDSIZ; // Offset of CEN size field within ENDHDR
|
||||
private static final int ENDOFF = ZipFile.ENDOFF; // Offset of CEN offset field within ENDHDR
|
||||
// Maximum allowed CEN size allowed by ZipFile
|
||||
private static int MAX_CEN_SIZE = Integer.MAX_VALUE - ENDHDR - 1;
|
||||
private static int MAX_CEN_SIZE = ArraysSupport.SOFT_MAX_ARRAY_LENGTH;
|
||||
|
||||
// Expected message when CEN size does not match file size
|
||||
private static final String INVALID_CEN_BAD_SIZE = "invalid END header (bad central directory size)";
|
||||
|
Loading…
Reference in New Issue
Block a user