Skip to content

Commit a41ce68

Browse files
committed
COMPRESS-463 throw exception when detecting a truncated stored entry
1 parent 64ed6dd commit a41ce68

File tree

4 files changed

+83
-1
lines changed

4 files changed

+83
-1
lines changed

src/changes/changes.xml

+5
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ The <action> type attribute can be add,update,fix,remove.
7474
It is now possible to specify the arguments of zstd-jni's
7575
ZstdOutputStream constructors via Commons Compress as well.
7676
</action>
77+
<action issue="COMPRESS-463" type="fix" date="2018-08-09">
78+
ZipArchiveInputStream#read would silently return -1 on a
79+
corrupted stored entry and even return > 0 after hitting the
80+
end of the archive.
81+
</action>
7782
</release>
7883
<release version="1.17" date="2018-06-03"
7984
description="Release 1.17">

src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,8 @@ private int readStored(final byte[] buffer, final int offset, final int length)
525525
buf.position(0);
526526
final int l = in.read(buf.array());
527527
if (l == -1) {
528-
return -1;
528+
buf.limit(0);
529+
throw new IOException("Truncated ZIP file");
529530
}
530531
buf.limit(l);
531532

src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java

+7
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ public void testRead7ZipMultiVolumeArchiveForStream() throws IOException {
9696
assertEquals("Truncated ZIP file", e.getMessage());
9797
}
9898

99+
try {
100+
zi.read(buffer);
101+
fail("shouldn't be able to read from truncated entry after exception");
102+
} catch (final IOException e) {
103+
assertEquals("Truncated ZIP file", e.getMessage());
104+
}
105+
99106
// and now we get another entry, which should also yield
100107
// an exception
101108
try {

src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java

+69
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,75 @@ private void multiByteReadConsistentlyReturnsMinusOneAtEof(File file) throws Exc
421421
}
422422
}
423423

424+
@Test
425+
public void singleByteReadThrowsAtEofForCorruptedStoredEntry() throws Exception {
426+
byte[] content;
427+
try (FileInputStream fs = new FileInputStream(getFile("COMPRESS-264.zip"))) {
428+
content = IOUtils.toByteArray(fs);
429+
}
430+
// make size much bigger than entry's real size
431+
for (int i = 17; i < 26; i++) {
432+
content[i] = (byte) 0xff;
433+
}
434+
try (ByteArrayInputStream in = new ByteArrayInputStream(content);
435+
ZipArchiveInputStream archive = new ZipArchiveInputStream(in)) {
436+
ArchiveEntry e = archive.getNextEntry();
437+
try {
438+
IOUtils.toByteArray(archive);
439+
fail("expected exception");
440+
} catch (IOException ex) {
441+
assertEquals("Truncated ZIP file", ex.getMessage());
442+
}
443+
try {
444+
archive.read();
445+
fail("expected exception");
446+
} catch (IOException ex) {
447+
assertEquals("Truncated ZIP file", ex.getMessage());
448+
}
449+
try {
450+
archive.read();
451+
fail("expected exception");
452+
} catch (IOException ex) {
453+
assertEquals("Truncated ZIP file", ex.getMessage());
454+
}
455+
}
456+
}
457+
458+
@Test
459+
public void multiByteReadThrowsAtEofForCorruptedStoredEntry() throws Exception {
460+
byte[] content;
461+
try (FileInputStream fs = new FileInputStream(getFile("COMPRESS-264.zip"))) {
462+
content = IOUtils.toByteArray(fs);
463+
}
464+
// make size much bigger than entry's real size
465+
for (int i = 17; i < 26; i++) {
466+
content[i] = (byte) 0xff;
467+
}
468+
byte[] buf = new byte[2];
469+
try (ByteArrayInputStream in = new ByteArrayInputStream(content);
470+
ZipArchiveInputStream archive = new ZipArchiveInputStream(in)) {
471+
ArchiveEntry e = archive.getNextEntry();
472+
try {
473+
IOUtils.toByteArray(archive);
474+
fail("expected exception");
475+
} catch (IOException ex) {
476+
assertEquals("Truncated ZIP file", ex.getMessage());
477+
}
478+
try {
479+
archive.read(buf);
480+
fail("expected exception");
481+
} catch (IOException ex) {
482+
assertEquals("Truncated ZIP file", ex.getMessage());
483+
}
484+
try {
485+
archive.read(buf);
486+
fail("expected exception");
487+
} catch (IOException ex) {
488+
assertEquals("Truncated ZIP file", ex.getMessage());
489+
}
490+
}
491+
}
492+
424493
private static byte[] readEntry(ZipArchiveInputStream zip, ZipArchiveEntry zae) throws IOException {
425494
final int len = (int)zae.getSize();
426495
final byte[] buff = new byte[len];

0 commit comments

Comments
 (0)