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
commit 864588382b21a5ea80d03e4e34fe6756ea8b131c Author: Stefan Bodewig <bode...@apache.org> AuthorDate: Sat May 1 15:41:02 2021 +0200 COMPRESS-575 confine sparse entry to its claimed realSize --- .../commons/compress/archivers/tar/TarArchiveEntry.java | 7 +++++++ .../commons/compress/archivers/tar/TarArchiveEntryTest.java | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java index de9f26f..0bd8344 100644 --- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java +++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java @@ -961,6 +961,13 @@ public class TarArchiveEntry implements ArchiveEntry, TarConstants, EntryStreamO + getName() + " too large."); } } + if (!orderedAndFiltered.isEmpty()) { + final TarArchiveStructSparse last = orderedAndFiltered.get(orderedAndFiltered.size() - 1); + if (last.getOffset() + last.getNumbytes() > getRealSize()) { + throw new IOException("Corrupted TAR archive. Sparse block extends beyond real size of the entry"); + } + } + return orderedAndFiltered; } diff --git a/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveEntryTest.java b/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveEntryTest.java index 47195ac..c0b1e97 100644 --- a/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveEntryTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveEntryTest.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Locale; import org.apache.commons.compress.AbstractTestCase; @@ -276,6 +277,8 @@ public class TarArchiveEntryTest implements TarConstants { @Test public void getOrderedSparseHeadersSortsAndFiltersSparseStructs() throws Exception { final TarArchiveEntry te = new TarArchiveEntry("test"); + // hacky way to set realSize + te.fillStarSparseData(Collections.singletonMap("SCHILY.realsize", "201")); te.setSparseHeaders(Arrays.asList(new TarArchiveStructSparse(10, 2), new TarArchiveStructSparse(20, 0), new TarArchiveStructSparse(15, 1), new TarArchiveStructSparse(0, 0))); final List<TarArchiveStructSparse> strs = te.getOrderedSparseHeaders(); @@ -288,6 +291,7 @@ public class TarArchiveEntryTest implements TarConstants { @Test(expected = IOException.class) public void getOrderedSparseHeadersRejectsOverlappingStructs() throws Exception { final TarArchiveEntry te = new TarArchiveEntry("test"); + te.fillStarSparseData(Collections.singletonMap("SCHILY.realsize", "201")); te.setSparseHeaders(Arrays.asList(new TarArchiveStructSparse(10, 5), new TarArchiveStructSparse(12, 1))); te.getOrderedSparseHeaders(); } @@ -295,10 +299,19 @@ public class TarArchiveEntryTest implements TarConstants { @Test(expected = IOException.class) public void getOrderedSparseHeadersRejectsStructsWithReallyBigNumbers() throws Exception { final TarArchiveEntry te = new TarArchiveEntry("test"); + te.fillStarSparseData(Collections.singletonMap("SCHILY.realsize", String.valueOf(Long.MAX_VALUE))); te.setSparseHeaders(Arrays.asList(new TarArchiveStructSparse(Long.MAX_VALUE, 2))); te.getOrderedSparseHeaders(); } + @Test(expected = IOException.class) + public void getOrderedSparseHeadersRejectsStructsPointingBeyondOutputEntry() throws Exception { + final TarArchiveEntry te = new TarArchiveEntry("test"); + te.setSparseHeaders(Arrays.asList(new TarArchiveStructSparse(200, 2))); + te.fillStarSparseData(Collections.singletonMap("SCHILY.realsize", "201")); + te.getOrderedSparseHeaders(); + } + private void assertGnuMagic(final TarArchiveEntry t) { assertEquals(MAGIC_GNU + VERSION_GNU_SPACE, readMagic(t)); }