-
CSR
-
Resolution: Approved
-
P4
-
None
-
behavioral
-
low
-
-
Java API
-
SE
Summary
ZipEntry(String), ZipEntry::setComment, and ZipEntry::setExtra did not take into account the combined length of the CEN Header, ZipEntry name, entry comment, and entry extra data size when validating the input for the constructor and methods.
Problem
This is a follow-on to JDK-8316141 and JDK-8336025 which addresses the fact that the validation checking in ZipFile and ZipOutputStream did not verify that the combined length of the CEN Header, which is 46 bytes, the entry name length, entry comment length, and entry extra length exceeds 65,535 bytes per the PKWare APP.NOTE 4.4.10, 4.4.11, & 4.4.12.
The maximum possible value for the above fields when you take into account the CEN Header length is 65,489. Because of this, we need to change the ZipEntry validation for the above fields to validate that the combined length does not exceed 65,535 bytes.
Solution
Update ZipEntry validation for the name, extra and comments fields so that the validation takes into account the combined length of the entry name, entry comment, entry extra data along with the 46 bytes for the CEN Header does not exceed 65,535 bytes.
Specification
The following updates will ba made to ZipEntry:
diff --git a/src/java.base/share/classes/java/util/zip/ZipEntry.java b/src/java.base/share/classes/java/util/zip/ZipEntry.java
index 026f6e466ea..35eae646ea8 100644
--- a/src/java.base/share/classes/java/util/zip/ZipEntry.java
+++ b/src/java.base/share/classes/java/util/zip/ZipEntry.java
@@ -91,11 +91,10 @@ public class ZipEntry implements ZipConstants, Cloneable {
*/
private static final long UPPER_DOSTIME_BOUND =
128L * 365 * 24 * 60 * 60 * 1000;
- // Maximum possible size of name length + comment length + extra length
- // for entries in order to not exceed 65,489 bytes minus 46 bytes for the CEN
- // header length
- private static final int MAX_NAME_COMMENT_EXTRA_SIZE =
- 0xFFFF - ZipFile.CENHDR;
+ // CEN header size + name length + comment length + extra length
+ // should not exceed 65,535 bytes per the PKWare APP.NOTE
+ // 4.4.10, 4.4.11, & 4.4.12.
+ private static final int MAX_COMBINED_CEN_HEADER_SIZE = 0xFFFF;
/**
* Creates a new ZIP entry with the specified name.
*
@@ -103,12 +102,12 @@ public class ZipEntry implements ZipConstants, Cloneable {
* The entry name
*
* @throws NullPointerException if the entry name is null
- * @throws IllegalArgumentException if the entry name is longer than
- * 65,489 bytes
+ * @throws IllegalArgumentException if the combined length of the entry name
+ * and the {@linkplain #CENHDR CEN Header size} exceeds 65,535 bytes.
*/
public ZipEntry(String name) {
Objects.requireNonNull(name, "name");
- if (name.length() > MAX_NAME_COMMENT_EXTRA_SIZE) {
+ if (!isCENHeaderValid(name, null, null)) {
throw new IllegalArgumentException("entry name too long");
}
this.name = name;
@@ -523,8 +522,10 @@ public int getMethod() {
* @param extra
* The extra field data bytes
*
- * @throws IllegalArgumentException if the length of the specified
- * extra field data is greater than 65,489 bytes
+ * @throws IllegalArgumentException if the combined length of the specified
+ * extra field data, the {@linkplain #getName() entry name},
+ * the {@linkplain #getComment() entry comment}, and the
+ * {@linkplain #CENHDR CEN Header size}, exceeds 65,535 bytes.
*
* @see #getExtra()
*/
@@ -545,7 +546,7 @@ public void setExtra(byte[] extra) {
*/
void setExtra0(byte[] extra, boolean doZIP64, boolean isLOC) {
if (extra != null) {
- if (extra.length > MAX_NAME_COMMENT_EXTRA_SIZE) {
+ if (!isCENHeaderValid(name, extra, comment)) {
throw new IllegalArgumentException("invalid extra field length");
}
// extra fields are in "HeaderID(2)DataSize(2)Data... format
@@ -647,13 +648,15 @@ public byte[] getExtra() {
/**
* Sets the optional comment string for the entry.
* @param comment the comment string
- * @throws IllegalArgumentException if the length of the specified
- * comment string is greater than 65,489 bytes
+ * @throws IllegalArgumentException if the combined length
+ * of the specified entry comment, the {@linkplain #getName() entry name},
+ * the {@linkplain #getExtra() extra field data}, and the
+ * {@linkplain #CENHDR CEN Header size}, exceeds 65,535 bytes.
* @see #getComment()
*/
public void setComment(String comment) {
if (comment != null) {
- if (comment.length() > MAX_NAME_COMMENT_EXTRA_SIZE) {
+ if (!isCENHeaderValid(name, extra, comment)) {
throw new IllegalArgumentException("entry comment too long");
}
}
@@ -707,4 +710,20 @@ public Object clone() {
throw new InternalError(e);
}
}
+
+ /**
+ * Validate that the CEN header size + name length + comment length + extra length
+ * do not exceed 65,535 bytes per the PKWare APP.NOTE
+ * 4.4.10, 4.4.11, & 4.4.12.
+ * @param name Zip entry name
+ * @param extra Zip extra data
+ * @param comment Zip entry comment
+ * @return true if valid CEN Header size; false otherwise
+ */
+ static boolean isCENHeaderValid(String name, byte[] extra, String comment) {
+ int clen = comment == null ? 0 : comment.length();
+ int elen = extra == null ? 0 : extra.length;
+ long headerSize = (long)CENHDR + name.length() + clen + elen;
+ return headerSize <= MAX_COMBINED_CEN_HEADER_SIZE;
+ }
}
- csr of
-
JDK-8340553 ZipEntry field validation does not take into account the size of a CEN header
-
- Resolved
-