From ebf99bfd4fe39ef5e0873839d3ca75c48b493d93 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Fri, 20 Nov 2020 14:41:36 +0200 Subject: [PATCH] BAEL-3641 fix for creating directories inside a zip and handling missing entry for root folder in windows-created archives --- .../java/com/baeldung/unzip/UnzipFile.java | 81 +++++++++++-------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/core-java-modules/core-java-io/src/main/java/com/baeldung/unzip/UnzipFile.java b/core-java-modules/core-java-io/src/main/java/com/baeldung/unzip/UnzipFile.java index 140d809d44..b81b343042 100644 --- a/core-java-modules/core-java-io/src/main/java/com/baeldung/unzip/UnzipFile.java +++ b/core-java-modules/core-java-io/src/main/java/com/baeldung/unzip/UnzipFile.java @@ -8,39 +8,50 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class UnzipFile { - public static void main(final String[] args) throws IOException { - final String fileZip = "src/main/resources/unzipTest/compressed.zip"; - final File destDir = new File("src/main/resources/unzipTest"); - final byte[] buffer = new byte[1024]; - final ZipInputStream zis = new ZipInputStream(new FileInputStream(fileZip)); - ZipEntry zipEntry = zis.getNextEntry(); - while (zipEntry != null) { - final File newFile = newFile(destDir, zipEntry); - final FileOutputStream fos = new FileOutputStream(newFile); - int len; - while ((len = zis.read(buffer)) > 0) { - fos.write(buffer, 0, len); - } - fos.close(); - zipEntry = zis.getNextEntry(); - } - zis.closeEntry(); - zis.close(); - } - - /** - * @see https://snyk.io/research/zip-slip-vulnerability - */ - public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException { - File destFile = new File(destinationDir, zipEntry.getName()); - - String destDirPath = destinationDir.getCanonicalPath(); - String destFilePath = destFile.getCanonicalPath(); - - if (!destFilePath.startsWith(destDirPath + File.separator)) { - throw new IOException("Entry is outside of the target dir: " + zipEntry.getName()); - } - - return destFile; - } + public static void main(final String[] args) throws IOException { + final String fileZip = "src/main/resources/unzipTest/compressed.zip"; + final File destDir = new File("src/main/resources/unzipTest"); + final byte[] buffer = new byte[1024]; + final ZipInputStream zis = new ZipInputStream(new FileInputStream(fileZip)); + ZipEntry zipEntry = zis.getNextEntry(); + while (zipEntry != null) { + final File newFile = newFile(destDir, zipEntry); + if (zipEntry.isDirectory()) { + if (!newFile.isDirectory() && !newFile.mkdirs()) { + throw new IOException("Failed to create directory " + newFile); + } + } else { + File parent = newFile.getParentFile(); + if (!parent.isDirectory() && !parent.mkdirs()) { + throw new IOException("Failed to create directory " + parent); + } + + final FileOutputStream fos = new FileOutputStream(newFile); + int len; + while ((len = zis.read(buffer)) > 0) { + fos.write(buffer, 0, len); + } + fos.close(); + } + zipEntry = zis.getNextEntry(); + } + zis.closeEntry(); + zis.close(); + } + + /** + * @see https://snyk.io/research/zip-slip-vulnerability + */ + public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException { + File destFile = new File(destinationDir, zipEntry.getName()); + + String destDirPath = destinationDir.getCanonicalPath(); + String destFilePath = destFile.getCanonicalPath(); + + if (!destFilePath.startsWith(destDirPath + File.separator)) { + throw new IOException("Entry is outside of the target dir: " + zipEntry.getName()); + } + + return destFile; + } } \ No newline at end of file