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) {