zip4j
zip4j copied to clipboard
Extracting ZIP with entry named `.` deletes the output directory
Version
Zip4j 2.11.5 Windows 10 (but might apply to Linux as well)
Description
When extracting a ZIP which contains an entry named ., Zip4j deletes the output directory before eventually throwing an exception. This is unexpected and looks like a bug. Zip4j should not delete the output directory, instead the user code should do that, if desired.
The underlying issue seems to be that Zip4j does not ignore an entry named . (respectively throw an exception) but instead treats it as regular file and tries to write to it. However, because it points to the existing output directory, trying to open the directory as file fails. Zip4j then erroneously tries to perform clean-up and actually deletes the directory here:
https://github.com/srikanth-lingala/zip4j/blob/c4c993cb143db99832eadd03699bd8228a9793b8/src/main/java/net/lingala/zip4j/tasks/AbstractExtractFileTask.java#L114-L117
Note: This actually applies to more than just the literal string ., for example also to . (with trailing space). So to detect this is might be best to check the result of getCanonicalPath(), or to adjust AbstractExtractFileTask#unzipFile to fail fast if outputFile is an existing directory (and not try to delete it).
Example code
Path zipPath = Files.createTempFile("zip-test", ".zip");
Path outputDir = Files.createTempDirectory("zip-test");
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipPath))) {
zipOut.putNextEntry(new ZipEntry("."));
}
try (ZipFile zipFile = new ZipFile(zipPath.toFile())) {
zipFile.extractAll(outputDir.toString());
} catch (ZipException e) {
System.out.println("Encountered expected exception: " + e);
} finally {
Files.delete(zipPath);
}
System.out.println("Output dir exists: " + Files.isDirectory(outputDir));
This will unexpectedly print
Output dir exists: false