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

ggregory 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 2d3a281e5 Check for Zip slip differently
2d3a281e5 is described below

commit 2d3a281e5344f8e6c2729c61b136600504fb1890
Author: Gary Gregory <garydgreg...@gmail.com>
AuthorDate: Wed Jan 17 07:27:22 2024 -0500

    Check for Zip slip differently
---
 .../org/apache/commons/compress/AbstractTest.java  | 28 ++++++++--------------
 1 file changed, 10 insertions(+), 18 deletions(-)

diff --git a/src/test/java/org/apache/commons/compress/AbstractTest.java 
b/src/test/java/org/apache/commons/compress/AbstractTest.java
index ea24bd363..a4070ebe9 100644
--- a/src/test/java/org/apache/commons/compress/AbstractTest.java
+++ b/src/test/java/org/apache/commons/compress/AbstractTest.java
@@ -48,8 +48,6 @@ import org.junit.jupiter.api.io.TempDir;
 
 public abstract class AbstractTest extends AbstractTempDirTest {
 
-    private static final String PARENT_PATH_SEGMENT = "..";
-
     protected interface StreamWrapper<I extends InputStream> {
         I wrap(InputStream inputStream) throws Exception;
     }
@@ -155,25 +153,27 @@ public abstract class AbstractTest extends 
AbstractTempDirTest {
      */
     protected File checkArchiveContent(final ArchiveInputStream<?> 
inputStream, final List<String> expected, final boolean cleanUp) throws 
Exception {
         final Path result = createTempDirectory("dir-result");
-
         try {
             ArchiveEntry entry;
             while ((entry = inputStream.getNextEntry()) != null) {
-                final Path outputFile = Paths.get(result.toString(), "result", 
checkParentSegment(entry));
+                final Path output = Paths.get(result.toString(), "result", 
entry.getName()).normalize();
+                if (!output.startsWith(result)) {
+                    throw new IOException("Zip slip " + output);
+                }
                 long bytesCopied = 0;
                 if (entry.isDirectory()) {
-                    Files.createDirectories(outputFile);
+                    Files.createDirectories(output);
                 } else {
-                    Files.createDirectories(outputFile.getParent());
-                    bytesCopied = Files.copy(inputStream, outputFile);
+                    Files.createDirectories(output.getParent());
+                    bytesCopied = Files.copy(inputStream, output);
                 }
                 final long size = entry.getSize();
                 if (size != ArchiveEntry.SIZE_UNKNOWN) {
                     assertEquals(size, bytesCopied, "Entry.size should equal 
bytes read.");
                 }
 
-                if (!Files.exists(outputFile)) {
-                    fail("Extraction failed: " + checkParentSegment(entry));
+                if (!Files.exists(output)) {
+                    fail("Extraction failed: " + entry.getName());
                 }
                 if (expected != null && 
!expected.remove(getExpectedString(entry))) {
                     fail("Unexpected entry: " + getExpectedString(entry));
@@ -219,14 +219,6 @@ public abstract class AbstractTest extends 
AbstractTempDirTest {
         }
     }
 
-    public static String checkParentSegment(final ArchiveEntry entry) {
-        final String name = entry.getName();
-        if (name.contains(PARENT_PATH_SEGMENT)) {
-            throw new IllegalStateException("Archive entry contains the parent 
path segment \"..\"");
-        }
-        return name;
-    }
-
     protected void closeQuietly(final Closeable closeable) {
         IOUtils.closeQuietly(closeable);
     }
@@ -327,7 +319,7 @@ public abstract class AbstractTest extends 
AbstractTempDirTest {
      * @return returns the entry name
      */
     protected String getExpectedString(final ArchiveEntry entry) {
-        return checkParentSegment(entry);
+        return entry.getName();
     }
 
     protected void setLongFileMode(final ArchiveOutputStream<?> outputStream) {

Reply via email to