-
CSR
-
Resolution: Approved
-
P3
-
None
-
behavioral
-
low
-
-
Java API
Summary
Add additional CEN Header validation to ZipOutputStream so that it is consistent with similar changes made to java.util.zip.ZipFile and the implementation of the ZIP file system provider.
Problem
As part of the fix for JDK-8316141 which was a follow up to JDK-8313765, validation was added to ZipFile
and Zip FS so that a ZipException is thrown when 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 corresponding change was not made to ZipOutputStream at the time
Solution
Enhance ZipOutputStream so that a ZipException is thrown when the combined length of the CEN header fields exceeds 65,535 bytes
As part of this change, the javadoc for ZipOutputStream will be clarified
Specification
The changes to ZipOutputStream.java
% git diff 6f8714ee src/java.base/share/classes/java/util/zip/ZipOutputStream.java
diff --git a/src/java.base/share/classes/java/util/zip/ZipOutputStream.java b/src/java.base/share/classes/java/util/zip/ZipOutputStream.java
index f68c27b265e..677f91295d5 100644
--- a/src/java.base/share/classes/java/util/zip/ZipOutputStream.java
+++ b/src/java.base/share/classes/java/util/zip/ZipOutputStream.java
@@ -378,6 +378,10 @@ public synchronized void write(byte[] b, int off, int len)
* Finishes writing the contents of the ZIP output stream without closing
* the underlying stream. Use this method when applying multiple filters
* in succession to the same output stream.
+ * <p>
+ * A ZipException will be thrown if the combined length, after encoding,
+ * of the entry name, the extra field data, the entry comment and
+ * {@linkplain #CENHDR CEN Header size}, exceeds 65,535 bytes.
* @throws ZipException if a ZIP file error has occurred
* @throws IOException if an I/O exception has occurred
*/
@@ -398,7 +402,9 @@ public void finish() throws IOException {
}
/**
- * Closes the ZIP output stream as well as the stream being filtered.
+ * Finishes writing the contents of the ZIP output stream and closes the
+ * underlying stream. The stream being filtered will also be closed.
+ *
* @throws ZipException if a ZIP file error has occurred
* @throws IOException if an I/O error has occurred
*/
@@ -589,7 +595,8 @@ private void writeCEN(XEntry xentry) throws IOException {
writeInt(csize); // compressed size
writeInt(size); // uncompressed size
byte[] nameBytes = zc.getBytes(e.name);
- writeShort(nameBytes.length);
+ int nlen = nameBytes.length;
+ writeShort(nlen);
int elen = getExtraLen(e.extra);
if (hasZip64) {
@@ -626,20 +633,19 @@ private void writeCEN(XEntry xentry) throws IOException {
}
}
writeShort(elen);
- byte[] commentBytes;
+ byte[] commentBytes = null;
+ int clen = 0;
if (e.comment != null) {
commentBytes = zc.getBytes(e.comment);
- writeShort(Math.min(commentBytes.length, 0xffff));
- } else {
- commentBytes = null;
- writeShort(0);
+ clen = Math.min(commentBytes.length, 0xffff);
}
+ writeShort(clen); // file comment length
writeShort(0); // starting disk number
writeShort(0); // internal file attributes (unused)
// extra file attributes, used for storing posix permissions etc.
writeInt(e.externalFileAttributes > 0 ? e.externalFileAttributes << 16 : 0);
writeInt(offset); // relative offset of local header
- writeBytes(nameBytes, 0, nameBytes.length);
+ writeBytes(nameBytes, 0, nlen);
// take care of EXTID_ZIP64 and EXTID_EXTT
if (hasZip64) {
@@ -679,9 +685,17 @@ private void writeCEN(XEntry xentry) throws IOException {
}
}
}
+
+ // 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.
+ long headerSize = (long)CENHDR + nlen + clen + elen;
+ if (headerSize > 0xFFFF ) {
+ throw new ZipException("invalid CEN header (bad header size)");
+ }
writeExtra(e.extra);
if (commentBytes != null) {
- writeBytes(commentBytes, 0, Math.min(commentBytes.length, 0xffff));
+ writeBytes(commentBytes, 0, clen);
}
}
- csr of
-
JDK-8336025 Improve ZipOutputSream validation of MAX CEN Header field limits
-
- Resolved
-