This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git


The following commit(s) were added to refs/heads/master by this push:
     new 42263d602 DumpArchiveEntry rejects out-of-range directory header count 
(#781)
42263d602 is described below

commit 42263d6029b5a50efedb40bb14b30eee9da059d4
Author: Gary Gregory <[email protected]>
AuthorDate: Sat Jul 4 08:13:23 2026 -0400

    DumpArchiveEntry rejects out-of-range directory header count (#781)
---
 .../commons/compress/archivers/dump/DumpArchiveEntry.java      | 10 ++++++++--
 .../commons/compress/archivers/dump/Compress712Test.java       |  2 +-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveEntry.java
 
b/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveEntry.java
index f4247f812..697f2aafe 100644
--- 
a/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveEntry.java
+++ 
b/src/main/java/org/apache/commons/compress/archivers/dump/DumpArchiveEntry.java
@@ -386,7 +386,7 @@ public static TYPE find(final int code) {
      *
      * @param buffer buffer to read content from.
      */
-    static DumpArchiveEntry parse(final byte[] buffer) {
+    static DumpArchiveEntry parse(final byte[] buffer) throws 
DumpArchiveException {
         final DumpArchiveEntry entry = new DumpArchiveEntry();
         final TapeSegmentHeader header = entry.header;
         header.type = 
DumpArchiveConstants.SEGMENT_TYPE.find(DumpArchiveUtil.convert32(buffer, 0));
@@ -420,7 +420,13 @@ static DumpArchiveEntry parse(final byte[] buffer) {
         entry.setUserId(DumpArchiveUtil.convert32(buffer, 144));
         entry.setGroupId(DumpArchiveUtil.convert32(buffer, 148));
         // two 32-bit spare values.
-        header.count = DumpArchiveUtil.convert32(buffer, 160);
+        final int headerCount = DumpArchiveUtil.convert32(buffer, 160);
+        // A tape segment header describes at most CDATA_LEN records, so a 
larger (or negative) count is
+        // corrupt. Without this the following product overflows int and 
yields a bogus datalen.
+        if (headerCount < 0 || headerCount >= 
DumpArchiveEntry.TapeSegmentHeader.CDATA_LEN) {
+            throw new DumpArchiveException("Invalid header count: " + 
headerCount + " (expected 0.." + (DumpArchiveEntry.TapeSegmentHeader.CDATA_LEN 
- 1) + ")");
+        }
+        header.count = headerCount;
         header.holes = 0;
         for (int i = 0; i < 512 && i < header.count; i++) {
             if (buffer[164 + i] == 0) {
diff --git 
a/src/test/java/org/apache/commons/compress/archivers/dump/Compress712Test.java 
b/src/test/java/org/apache/commons/compress/archivers/dump/Compress712Test.java
index 127095da1..8b6650d6d 100644
--- 
a/src/test/java/org/apache/commons/compress/archivers/dump/Compress712Test.java
+++ 
b/src/test/java/org/apache/commons/compress/archivers/dump/Compress712Test.java
@@ -267,7 +267,7 @@ public void testPart2() throws IOException {
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
         try (DumpArchiveInputStream is = new DumpArchiveInputStream(new 
ByteArrayInputStream(data))) {
-            assertThrows(IndexOutOfBoundsException.class, () -> {
+            assertThrows(DumpArchiveException.class, () -> {
                 while (is.getNextEntry() != null) {
                     is.read(new byte[1024]);
                 }

Reply via email to