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));
     }

Reply via email to