From 2f169c27bf0252229c6a96ea18d9b6f9348c6b9e Mon Sep 17 00:00:00 2001 From: Marian Koncek Date: Fri, 5 Oct 2018 13:10:18 +0200 Subject: [PATCH] COMPRESS-463 throw exception when detecting a truncated stored entry --- .../archivers/zip/ZipArchiveInputStream.java | 3 +- .../zip/Maven221MultiVolumeTest.java | 7 ++ .../zip/ZipArchiveInputStreamTest.java | 69 +++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) 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 729d92e..4c239ec 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 @@ -523,7 +523,8 @@ public class ZipArchiveInputStream extends ArchiveInputStream implements InputSt buf.position(0); final int l = in.read(buf.array()); if (l == -1) { - return -1; + buf.limit(0); + throw new IOException("Truncated ZIP file"); } buf.limit(l); diff --git a/src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java b/src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java index c28f3de..0a905e3 100644 --- a/src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/zip/Maven221MultiVolumeTest.java @@ -96,6 +96,13 @@ public class Maven221MultiVolumeTest { assertEquals("Truncated ZIP file", e.getMessage()); } + try { + zi.read(buffer); + fail("shouldn't be able to read from truncated entry after exception"); + } catch (final IOException e) { + assertEquals("Truncated ZIP file", e.getMessage()); + } + // and now we get another entry, which should also yield // an exception try { 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 5d1cdb1..5bf003b 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 @@ -340,6 +340,75 @@ public class ZipArchiveInputStreamTest { } } + @Test + public void singleByteReadThrowsAtEofForCorruptedStoredEntry() throws Exception { + byte[] content; + try (FileInputStream fs = new FileInputStream(getFile("COMPRESS-264.zip"))) { + content = IOUtils.toByteArray(fs); + } + // make size much bigger than entry's real size + for (int i = 17; i < 26; i++) { + content[i] = (byte) 0xff; + } + try (ByteArrayInputStream in = new ByteArrayInputStream(content); + ZipArchiveInputStream archive = new ZipArchiveInputStream(in)) { + ArchiveEntry e = archive.getNextEntry(); + try { + IOUtils.toByteArray(archive); + fail("expected exception"); + } catch (IOException ex) { + assertEquals("Truncated ZIP file", ex.getMessage()); + } + try { + archive.read(); + fail("expected exception"); + } catch (IOException ex) { + assertEquals("Truncated ZIP file", ex.getMessage()); + } + try { + archive.read(); + fail("expected exception"); + } catch (IOException ex) { + assertEquals("Truncated ZIP file", ex.getMessage()); + } + } + } + + @Test + public void multiByteReadThrowsAtEofForCorruptedStoredEntry() throws Exception { + byte[] content; + try (FileInputStream fs = new FileInputStream(getFile("COMPRESS-264.zip"))) { + content = IOUtils.toByteArray(fs); + } + // make size much bigger than entry's real size + for (int i = 17; i < 26; i++) { + content[i] = (byte) 0xff; + } + byte[] buf = new byte[2]; + try (ByteArrayInputStream in = new ByteArrayInputStream(content); + ZipArchiveInputStream archive = new ZipArchiveInputStream(in)) { + ArchiveEntry e = archive.getNextEntry(); + try { + IOUtils.toByteArray(archive); + fail("expected exception"); + } catch (IOException ex) { + assertEquals("Truncated ZIP file", ex.getMessage()); + } + try { + archive.read(buf); + fail("expected exception"); + } catch (IOException ex) { + assertEquals("Truncated ZIP file", ex.getMessage()); + } + try { + archive.read(buf); + fail("expected exception"); + } catch (IOException ex) { + assertEquals("Truncated ZIP file", ex.getMessage()); + } + } + } + private static byte[] readEntry(ZipArchiveInputStream zip, ZipArchiveEntry zae) throws IOException { final int len = (int)zae.getSize(); final byte[] buff = new byte[len]; -- 2.17.1