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 2021/05/01 13:48:30 UTC

[commons-compress] 03/05: COMPRESS-575 confine sparse entry to its claimed realSize

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 <bo...@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));
     }