You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
UrlsController/src/main/java/eu/openaire/urls_controller/util/FileUnZipper.java

62 lines
2.2 KiB
Java

package eu.openaire.urls_controller.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class FileUnZipper {
private static final Logger logger = LoggerFactory.getLogger(FileUnZipper.class);
public static void unzipFolder(Path source, Path target) throws Exception
{
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(source.toFile())))
{
// Iterate over the files in zip and un-zip them.
ZipEntry zipEntry = zis.getNextEntry();
while ( zipEntry != null )
{
Path targetPath = zipSlipProtect(zipEntry, target);
if ( zipEntry.getName().endsWith(File.separator) ) // If we have a directory.
Files.createDirectories(targetPath);
else {
// Some zip stored file path only, need create parent directories, e.g data/folder/file.txt
if ( targetPath.getParent() != null ) {
if ( Files.notExists(targetPath.getParent()) ) {
Files.createDirectories(targetPath.getParent());
}
}
Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
}
zipEntry = zis.getNextEntry();
}
zis.closeEntry();
}
}
// Protect from a Zip Slip attack: https://snyk.io/research/zip-slip-vulnerability
public static Path zipSlipProtect(ZipEntry zipEntry, Path targetDir) throws IOException
{
Path targetDirResolved = targetDir.resolve(zipEntry.getName());
// Make sure normalized file still has targetDir as its prefix, else throw an exception.
Path normalizePath = targetDirResolved.normalize();
if ( !normalizePath.startsWith(targetDir) ) {
throw new IOException("Bad zip entry: " + zipEntry.getName());
}
return normalizePath;
}
}