From 6594a2d66f7f060dafcbbf094dd60676db19a842 Mon Sep 17 00:00:00 2001
From: Stefan Bodewig <bodewig@apache.org>
Date: Sat, 10 Jul 2021 11:10:12 +0200
Subject: [PATCH] port some fixes from Commons Compress

---
 .../org/apache/tools/tar/TarInputStream.java  |  7 +++++--
 .../org/apache/tools/zip/AsiExtraField.java   | 12 +++++++----
 src/main/org/apache/tools/zip/ZipFile.java    | 20 ++++++++++++++++++-
 3 files changed, 32 insertions(+), 7 deletions(-)

Index: apache-ant-1.9.4/src/main/org/apache/tools/tar/TarInputStream.java
===================================================================
--- apache-ant-1.9.4.orig/src/main/org/apache/tools/tar/TarInputStream.java
+++ apache-ant-1.9.4/src/main/org/apache/tools/tar/TarInputStream.java
@@ -431,18 +431,25 @@ public class TarInputStream extends Filt
                         if (ch == '='){ // end of keyword
                             String keyword = coll.toString("UTF-8");
                             // Get rest of entry
-                            byte[] rest = new byte[len - read];
-                            int got = i.read(rest);
-                            if (got != len - read){
+                            final int restLen = len - read;
+                            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                            int got = 0;
+                            while (got < restLen && (ch = i.read()) != -1) {
+                                bos.write((byte) ch);
+                                got++;
+                            }
+                            bos.close();
+                            if (got != restLen) {
                                 throw new IOException("Failed to read "
                                                       + "Paxheader. Expected "
-                                                      + (len - read)
+                                                      + restLen
                                                       + " bytes, read "
                                                       + got);
                             }
+                            byte[] rest = bos.toByteArray();
                             // Drop trailing NL
                             String value = new String(rest, 0,
-                                                      len - read - 1, "UTF-8");
+                                                      restLen - 1, "UTF-8");
                             headers.put(keyword, value);
                             break;
                         }
Index: apache-ant-1.9.4/src/main/org/apache/tools/zip/AsiExtraField.java
===================================================================
--- apache-ant-1.9.4.orig/src/main/org/apache/tools/zip/AsiExtraField.java
+++ apache-ant-1.9.4/src/main/org/apache/tools/zip/AsiExtraField.java
@@ -307,14 +307,18 @@ public class AsiExtraField implements Zi
 
         int newMode = ZipShort.getValue(tmp, 0);
         // CheckStyle:MagicNumber OFF
-        byte[] linkArray = new byte[(int) ZipLong.getValue(tmp, 2)];
+        final int linkArrayLength = (int) ZipLong.getValue(tmp, 2);
+        if (linkArrayLength < 0 || linkArrayLength > tmp.length - 10) {
+            throw new ZipException("Bad symbolic link name length " + linkArrayLength
+                + " in ASI extra field");
+        }
         uid = ZipShort.getValue(tmp, 6);
         gid = ZipShort.getValue(tmp, 8);
-
-        if (linkArray.length == 0) {
+        if (linkArrayLength == 0) {
             link = "";
         } else {
-            System.arraycopy(tmp, 10, linkArray, 0, linkArray.length);
+            final byte[] linkArray = new byte[linkArrayLength];
+            System.arraycopy(tmp, 10, linkArray, 0, linkArrayLength);
             link = new String(linkArray); // Uses default charset - see class Javadoc
         }
         // CheckStyle:MagicNumber ON
Index: apache-ant-1.9.4/src/main/org/apache/tools/zip/ZipFile.java
===================================================================
--- apache-ant-1.9.4.orig/src/main/org/apache/tools/zip/ZipFile.java
+++ apache-ant-1.9.4/src/main/org/apache/tools/zip/ZipFile.java
@@ -532,6 +532,9 @@ public class ZipFile {
         ze.setExternalAttributes(ZipLong.getValue(CFH_BUF, off));
         off += WORD;
 
+        if (archive.length() - archive.getFilePointer() < fileNameLen) {
+            throw new EOFException();
+        }
         byte[] fileName = new byte[fileNameLen];
         archive.readFully(fileName);
         ze.setName(entryEncoding.decode(fileName), fileName);
@@ -541,12 +544,18 @@ public class ZipFile {
         // data offset will be filled later
         entries.add(ze);
 
+        if (archive.length() - archive.getFilePointer() < extraLen) {
+            throw new EOFException();
+        }
         byte[] cdExtraData = new byte[extraLen];
         archive.readFully(cdExtraData);
         ze.setCentralDirectoryExtra(cdExtraData);
 
         setSizesAndOffsetFromZip64Extra(ze, offset, diskStart);
 
+        if (archive.length() - archive.getFilePointer() < commentLen) {
+            throw new EOFException();
+        }
         byte[] comment = new byte[commentLen];
         archive.readFully(comment);
         ze.setComment(entryEncoding.decode(comment));
@@ -872,9 +881,18 @@ public class ZipFile {
                 }
                 lenToSkip -= skipped;
             }
+            if (archive.length() - archive.getFilePointer() < extraFieldLen) {
+                throw new EOFException();
+            }
             byte[] localExtraData = new byte[extraFieldLen];
             archive.readFully(localExtraData);
-            ze.setExtra(localExtraData);
+            try {
+                ze.setExtra(localExtraData);
+            } catch (RuntimeException ex) {
+                final ZipException z = new ZipException("Invalid extra data in entry " + ze.getName());
+                z.initCause(ex);
+                throw z;
+            }
             offsetEntry.dataOffset = offset + LFH_OFFSET_FOR_FILENAME_LENGTH
                 + SHORT + SHORT + fileNameLen + extraFieldLen;
 
