diff --git a/solidify-util/src/main/java/ch/unige/solidify/util/ZipTool.java b/solidify-util/src/main/java/ch/unige/solidify/util/ZipTool.java index 4ce7d6ec1ad60d1c94bd31e98b59e218aaa4a7c0..b3e310b9d86a2b6465719e89eafa56376ae61c1c 100644 --- a/solidify-util/src/main/java/ch/unige/solidify/util/ZipTool.java +++ b/solidify-util/src/main/java/ch/unige/solidify/util/ZipTool.java @@ -78,7 +78,7 @@ public class ZipTool { this.archive = Paths.get(archive); } - public static boolean unzipFiles(InputStream zipData, Path destination, List<String> list, String relativeFolder, + public static boolean unzipFiles(InputStream zipData, Path destination, List<String> fileAndDirectoryList, String relativeFolder, boolean checkEmptyDestination) { int entryCount = 0; long totalSize = 0; @@ -89,7 +89,7 @@ public class ZipTool { ZipEntry ze = zis.getNextEntry(); // Extract zip entry while (ze != null) { - if (isFileCandidate(list, ze)) { + if (needToBeExtracted(fileAndDirectoryList, ze)) { totalSize += extractFile(zis, ze, destination, relativeFolder); entryCount++; } @@ -140,7 +140,6 @@ public class ZipTool { private static long extractFile(ZipInputStream zipFile, ZipEntry zipEntry, Path destination, String relativeFolder) throws IOException { final Path newFile = checkDestination(zipEntry, destination, relativeFolder); - zipEntry.getCompressedSize(); long fileSize = 0; if (newFile != null) { @@ -159,19 +158,28 @@ public class ZipTool { return fileSize; } - private static boolean isFileCandidate(List<String> list, ZipEntry ze) { - if (list == null) { + private static boolean needToBeExtracted(List<String> fileAndDirectoryList, ZipEntry ze) { + if (fileAndDirectoryList == null) { return true; } - for (final String f : list) { + for (final String file : fileAndDirectoryList) { + final String normalizedPath = normalizePath(file); final String zePath = ze.getName(); - if (zePath.startsWith(normalizePath(f))) { - return true; + if (zePath.equals(normalizedPath) || zePath.startsWith(useAsDirectory(normalizedPath))) { + return true; } } return false; } + private static String useAsDirectory(String path) { + if (path.endsWith(File.separator)) { + return path; + } else { + return path + File.separator; + } + } + private static String normalizePath(String path) { if (File.separatorChar == '/') { // Linux compatible OS @@ -308,8 +316,8 @@ public class ZipTool { return extractedFiles; } - public boolean unzipFiles(Path destination, List<String> list, boolean checkEmptyDestination) { - return this.unzipFiles(destination, list, null, checkEmptyDestination); + public boolean unzipFiles(Path destination, List<String> fileAndDirectoryList, boolean checkEmptyDestination) { + return this.unzipFiles(destination, fileAndDirectoryList, null, checkEmptyDestination); } public boolean unzipFiles(URI destination, boolean checkEmptyDestination) { @@ -406,9 +414,9 @@ public class ZipTool { } } - private boolean unzipFiles(Path destination, List<String> list, String relativeFolder, boolean checkEmptyDestination) { + private boolean unzipFiles(Path destination, List<String> fileAndDirectoryList, String relativeFolder, boolean checkEmptyDestination) { try (InputStream is = new BufferedInputStream(new FileInputStream(this.getArchive()), SolidifyConstants.BUFFER_SIZE)) { - return unzipFiles(is, destination, list, relativeFolder, checkEmptyDestination); + return unzipFiles(is, destination, fileAndDirectoryList, relativeFolder, checkEmptyDestination); } catch (final IOException e) { log.error("Problem in unzipping package ({})", this.archive, e); } diff --git a/solidify-util/src/test/java/ch/unige/solidify/test/util/ZipTest.java b/solidify-util/src/test/java/ch/unige/solidify/test/util/ZipTest.java index 8778cfeb2cf1ac092a3d9b1dc0cb2dc215a50ac4..986a0d1466064efa76c761391960df578eb046d9 100644 --- a/solidify-util/src/test/java/ch/unige/solidify/test/util/ZipTest.java +++ b/solidify-util/src/test/java/ch/unige/solidify/test/util/ZipTest.java @@ -57,6 +57,8 @@ class ZipTest { private static final String PATH_FILE1 = "dlcm/dlcm.xml"; private static final String PATH_FILE2 = "dlcm/include/datacite-funderIdentifierType-v4.xsd"; private static final String PATH_FILE3 = "json/geo-location.json"; + private static final String PATH_FILE_WITH_INCLUDED_FILE_NAME = "zip/test.txt"; + private static final String PATH_FILE_WITH_INCLUDING_FILE_NAME = "zip/test.txt.orig"; private static final String UNZIP_DIR = "unzip"; private static final String ZIP_ARCHIVE = "test.zip"; private static final String ZIP_DIR = "dlcm"; @@ -154,20 +156,19 @@ class ZipTest { assertEquals(1, zipTool.getFolderNumber()); } - @Test - void partialUnzipArchiveTest() throws IOException { - final Path zipDir = Paths.get(new ClassPathResource(ZIP_DIR).getURI()); + @ParameterizedTest + @ValueSource(strings = {"zip/zip_test.zip", "zip/windows_zip_test.zip"}) + void partialUnzipArchiveTest(String zipFile) throws IOException { + final Path zipFilePath = Paths.get(new ClassPathResource(zipFile).getURI()); final Path unzipDir = Paths .get(System.getProperty("java.io.tmpdir") + File.separatorChar + UNZIP_DIR); - final ZipTool zipTool = new ZipTool(ZIP_ARCHIVE); - final List<String> extractList = Arrays.asList("dlcm.xsd", "include/datacite-"); - assertTrue(zipTool.zipFiles(zipDir)); + final ZipTool zipTool = new ZipTool(zipFilePath.toString()); + final List<String> extractList = Arrays.asList("Folder with file", "root file.txt"); assertTrue(zipTool.unzipFiles(unzipDir, extractList, true)); final List<Path> fileList = new ArrayList<>(); fileList.addAll(FileTool.readFolder(unzipDir)); - fileList.addAll(FileTool.readFolder(unzipDir.resolve(INCLUDE))); - assertEquals(ZIP_XSD_NUMBER, fileList.size()); - FileTool.deleteFile(Paths.get(ZIP_ARCHIVE)); + fileList.addAll(FileTool.readFolder(unzipDir.resolve("Folder with file"))); + assertEquals(2, fileList.size()); assertTrue(FileTool.deleteFolder(unzipDir)); } @@ -240,6 +241,24 @@ class ZipTest { assertTrue(FileTool.deleteFolder(unzipDir), "Wrong file number"); } + @Test + void extractExactFilePath() throws IOException { + final Path zipDir = Paths.get(new ClassPathResource(".").getURI()); + final ZipTool zipTool = new ZipTool(ZIP_ARCHIVE); + final Path unzipDir = Paths.get(System.getProperty("java.io.tmpdir") + File.separatorChar + UNZIP_DIR); + final List<Path> filesToAdd = new ArrayList<>(); + filesToAdd.add(Paths.get(new ClassPathResource(PATH_FILE_WITH_INCLUDED_FILE_NAME).getURI())); + filesToAdd.add(Paths.get(new ClassPathResource(PATH_FILE_WITH_INCLUDING_FILE_NAME).getURI())); + assertTrue(zipTool.addFilesToZip(zipDir, filesToAdd, null, false, false)); + assertTrue(zipTool.checkZip()); + assertEquals(2, zipTool.getEntryNumber()); + zipTool.unzipFiles(unzipDir, List.of(PATH_FILE_WITH_INCLUDED_FILE_NAME),true); + List<Path> extractedFiles = FileTool.readFolder(unzipDir.resolve("zip")); + FileTool.deleteFile(Paths.get(ZIP_ARCHIVE)); + assertTrue(FileTool.deleteFolder(unzipDir)); + assertEquals(1, extractedFiles.size()); + } + @ParameterizedTest @ValueSource(strings = { "zip-slip.zip", "zip-slip-win.zip" }) void unzipZipSlipTest(String zipFile) throws IOException { @@ -247,7 +266,7 @@ class ZipTest { } @ParameterizedTest - @ValueSource(strings = { "r.zip", "datafiles-encoded.zip" }) + @ValueSource(strings = { "r.zip", "datafiles-encoded.zip", "windows_zip_test.zip"}) void unzipTest(String zipFile) throws IOException { this.runUnzipTest(zipFile, false); } diff --git a/solidify-util/src/test/resources/zip/test.txt b/solidify-util/src/test/resources/zip/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..9daeafb9864cf43055ae93beb0afd6c7d144bfa4 --- /dev/null +++ b/solidify-util/src/test/resources/zip/test.txt @@ -0,0 +1 @@ +test diff --git a/solidify-util/src/test/resources/zip/test.txt.orig b/solidify-util/src/test/resources/zip/test.txt.orig new file mode 100644 index 0000000000000000000000000000000000000000..9daeafb9864cf43055ae93beb0afd6c7d144bfa4 --- /dev/null +++ b/solidify-util/src/test/resources/zip/test.txt.orig @@ -0,0 +1 @@ +test diff --git a/solidify-util/src/test/resources/zip/windows_zip_test.zip b/solidify-util/src/test/resources/zip/windows_zip_test.zip new file mode 100644 index 0000000000000000000000000000000000000000..8ee4059b3322ab52031f1911afbdb4e489c2ab5b Binary files /dev/null and b/solidify-util/src/test/resources/zip/windows_zip_test.zip differ diff --git a/solidify-util/src/test/resources/zip/zip_test.zip b/solidify-util/src/test/resources/zip/zip_test.zip new file mode 100644 index 0000000000000000000000000000000000000000..ead8712760fb22bfa4856b12e05c328c5d2392bf Binary files /dev/null and b/solidify-util/src/test/resources/zip/zip_test.zip differ