You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2020/05/23 20:00:34 UTC
[commons-compress] branch master updated: COMPRESS-523 be more
defensive when skipping over remainder of archive
This is an automated email from the ASF dual-hosted git repository.
bodewig 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 2ea0e46 COMPRESS-523 be more defensive when skipping over remainder of archive
2ea0e46 is described below
commit 2ea0e4647c6826bea9b04acb104a2954003e8b5c
Author: Stefan Bodewig <bo...@apache.org>
AuthorDate: Sat May 23 21:59:47 2020 +0200
COMPRESS-523 be more defensive when skipping over remainder of archive
---
src/changes/changes.xml | 3 +++
.../archivers/zip/ZipArchiveInputStream.java | 29 +++++++++++++++-------
.../archivers/zip/ZipArchiveInputStreamTest.java | 14 +++++++++++
3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 41f79f6..e454ea7 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -81,6 +81,9 @@ The <action> type attribute can be add,update,fix,remove.
IOException rather than a RuntimeException if the zip64 extra
field of an enty could not be parsed.
</action>
+ <action issue="COMPRESS-523" type="fix" date="2020-05-23">
+ Improved detection of corrupt ZIP archives in ZipArchiveInputStream.
+ </action>
</release>
<release version="1.20" date="2020-02-08"
description="Release 1.20">
diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
index 7d15345..5306590 100644
--- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
@@ -1055,19 +1055,28 @@ public class ZipArchiveInputStream extends ArchiveInputStream implements InputSt
// skip over central directory. One LFH has been read too much
// already. The calculation discounts file names and extra
// data so it will be too short.
- realSkip((long) entriesRead * CFH_LEN - LFH_LEN);
- findEocdRecord();
- realSkip((long) ZipFile.MIN_EOCD_SIZE - WORD /* signature */ - SHORT /* comment len */);
- readFully(shortBuf);
- // file comment
- realSkip(ZipShort.getValue(shortBuf));
+ if (entriesRead > 0) {
+ realSkip((long) entriesRead * CFH_LEN - LFH_LEN);
+ boolean foundEocd = findEocdRecord();
+ if (foundEocd) {
+ realSkip((long) ZipFile.MIN_EOCD_SIZE - WORD /* signature */ - SHORT /* comment len */);
+ readFully(shortBuf);
+ // file comment
+ final int commentLen = ZipShort.getValue(shortBuf);
+ if (commentLen >= 0) {
+ realSkip(commentLen);
+ return;
+ }
+ }
+ }
+ throw new IOException("Truncated ZIP file");
}
/**
* Reads forward until the signature of the "End of central
* directory" record is found.
*/
- private void findEocdRecord() throws IOException {
+ private boolean findEocdRecord() throws IOException {
int currentByte = -1;
boolean skipReadCall = false;
while (skipReadCall || (currentByte = readOneByte()) > -1) {
@@ -1092,12 +1101,14 @@ public class ZipArchiveInputStream extends ArchiveInputStream implements InputSt
continue;
}
currentByte = readOneByte();
- if (currentByte == -1
- || currentByte == ZipArchiveOutputStream.EOCD_SIG[3]) {
+ if (currentByte == -1) {
break;
+ } else if (currentByte == ZipArchiveOutputStream.EOCD_SIG[3]) {
+ return true;
}
skipReadCall = isFirstByteOfEocdSig(currentByte);
}
+ return false;
}
/**
diff --git a/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java b/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java
index fb468f1..44ff4b3 100644
--- a/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java
@@ -696,6 +696,20 @@ public class ZipArchiveInputStreamTest {
});
}
+ @Test
+ /**
+ * @see https://issues.apache.org/jira/browse/COMPRESS-523
+ */
+ public void throwsIfZip64ExtraCouldNotBeUnderstoodY() throws Exception {
+ thrown.expect(IOException.class);
+ thrown.expectMessage("Truncated ZIP file");
+ fuzzingTest(new int[] {
+ 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x14, 0x00, 0x08, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xbe, 0x00, 0x00,
+ 0x00, 0xb7, 0xe8, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00
+ });
+ }
+
private static byte[] readEntry(ZipArchiveInputStream zip, ZipArchiveEntry zae) throws IOException {
final int len = (int)zae.getSize();
final byte[] buff = new byte[len];