This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git
The following commit(s) were added to refs/heads/master by this push:
new 18e026454 fix rcount field width in x0015 and x0016 certificate id
extra fields (#787)
18e026454 is described below
commit 18e02645410767d0a21bbffe6ba7f650077fa47b
Author: KALI 834X <[email protected]>
AuthorDate: Sat Jul 18 01:54:13 2026 +0530
fix rcount field width in x0015 and x0016 certificate id extra fields (#787)
x0015_certificateidforfile and x0016_certificateidforcentraldirectory read
the certificate-id extra field's rcount as a 2-byte zipshort at offset and
hashalg at offset+2, but the layout documented on both classes (and the reading
in the sibling x0017_strongencryptionheader) puts a 4-byte rcount first with
hashalg at offset+4. getrecordcount therefore exposed only the low 16 bits of
rcount and gethashalgorithm was derived from its high half. read rcount as a
ziplong and hashalg at offs [...]
---
.../archivers/zip/X0015_CertificateIdForFile.java | 6 +--
.../X0016_CertificateIdForCentralDirectory.java | 6 +--
.../zip/X0015_X0016_CertificateIdTest.java | 63 ++++++++++++++++++++++
3 files changed, 69 insertions(+), 6 deletions(-)
diff --git
a/src/main/java/org/apache/commons/compress/archivers/zip/X0015_CertificateIdForFile.java
b/src/main/java/org/apache/commons/compress/archivers/zip/X0015_CertificateIdForFile.java
index 939477795..ba6423030 100644
---
a/src/main/java/org/apache/commons/compress/archivers/zip/X0015_CertificateIdForFile.java
+++
b/src/main/java/org/apache/commons/compress/archivers/zip/X0015_CertificateIdForFile.java
@@ -80,9 +80,9 @@ public int getRecordCount() {
@Override
public void parseFromCentralDirectoryData(final byte[] data, final int
offset, final int length) throws ZipException {
- assertMinimalLength(4, length);
+ assertMinimalLength(6, length);
super.parseFromCentralDirectoryData(data, offset, length);
- this.rcount = ZipShort.getValue(data, offset);
- this.hashAlg =
HashAlgorithm.getAlgorithmByCode(ZipShort.getValue(data, offset + 2));
+ this.rcount = (int) ZipLong.getValue(data, offset);
+ this.hashAlg =
HashAlgorithm.getAlgorithmByCode(ZipShort.getValue(data, offset + 4));
}
}
diff --git
a/src/main/java/org/apache/commons/compress/archivers/zip/X0016_CertificateIdForCentralDirectory.java
b/src/main/java/org/apache/commons/compress/archivers/zip/X0016_CertificateIdForCentralDirectory.java
index 078f5ef73..73e2cbb95 100644
---
a/src/main/java/org/apache/commons/compress/archivers/zip/X0016_CertificateIdForCentralDirectory.java
+++
b/src/main/java/org/apache/commons/compress/archivers/zip/X0016_CertificateIdForCentralDirectory.java
@@ -81,9 +81,9 @@ public int getRecordCount() {
@Override
public void parseFromCentralDirectoryData(final byte[] data, final int
offset, final int length) throws ZipException {
- assertMinimalLength(4, length);
+ assertMinimalLength(6, length);
// TODO: double check we really do not want to call super here
- this.rcount = ZipShort.getValue(data, offset);
- this.hashAlg =
HashAlgorithm.getAlgorithmByCode(ZipShort.getValue(data, offset + 2));
+ this.rcount = (int) ZipLong.getValue(data, offset);
+ this.hashAlg =
HashAlgorithm.getAlgorithmByCode(ZipShort.getValue(data, offset + 4));
}
}
diff --git
a/src/test/java/org/apache/commons/compress/archivers/zip/X0015_X0016_CertificateIdTest.java
b/src/test/java/org/apache/commons/compress/archivers/zip/X0015_X0016_CertificateIdTest.java
new file mode 100644
index 000000000..c04e97d64
--- /dev/null
+++
b/src/test/java/org/apache/commons/compress/archivers/zip/X0015_X0016_CertificateIdTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.commons.compress.archivers.zip;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.zip.ZipException;
+
+import
org.apache.commons.compress.archivers.zip.PKWareExtraHeader.HashAlgorithm;
+import org.junit.jupiter.api.Test;
+
+class X0015_X0016_CertificateIdTest {
+
+ // RCount 0x00010001 (4 bytes LE) then HashAlg SHA256 0x800C (2 bytes LE).
+ // The low 16 bits of RCount (1) and its high 16 bits (1) are chosen so
that a 2-byte read of RCount at
+ // the wrong width/offset would yield rcount == 1 and hashAlg == CRC32
(code 1) instead of the real values.
+ private static final byte[] CENTRAL_DATA = { 0x01, 0x00, 0x01, 0x00, 0x0C,
(byte) 0x80 };
+
+ @Test
+ void testX0015ReadsFourByteRecordCountAndHashAlg() throws ZipException {
+ final X0015_CertificateIdForFile field = new
X0015_CertificateIdForFile();
+ field.parseFromCentralDirectoryData(CENTRAL_DATA, 0,
CENTRAL_DATA.length);
+ assertEquals(0x00010001, field.getRecordCount());
+ assertEquals(HashAlgorithm.SHA256, field.getHashAlgorithm());
+ }
+
+ @Test
+ void testX0016ReadsFourByteRecordCountAndHashAlg() throws ZipException {
+ final X0016_CertificateIdForCentralDirectory field = new
X0016_CertificateIdForCentralDirectory();
+ field.parseFromCentralDirectoryData(CENTRAL_DATA, 0,
CENTRAL_DATA.length);
+ assertEquals(0x00010001, field.getRecordCount());
+ assertEquals(HashAlgorithm.SHA256, field.getHashAlgorithm());
+ }
+
+ @Test
+ void testX0015RejectsTruncatedHashAlg() {
+ final X0015_CertificateIdForFile field = new
X0015_CertificateIdForFile();
+ assertThrows(ZipException.class, () ->
field.parseFromCentralDirectoryData(CENTRAL_DATA, 0, 5));
+ }
+
+ @Test
+ void testX0016RejectsTruncatedHashAlg() {
+ final X0016_CertificateIdForCentralDirectory field = new
X0016_CertificateIdForCentralDirectory();
+ assertThrows(ZipException.class, () ->
field.parseFromCentralDirectoryData(CENTRAL_DATA, 0, 5));
+ }
+}