zip4j
zip4j copied to clipboard
Adding comments to an existing zip64 file can corrupt the file
The following code can reproduce the exception.
import java.io.ByteArrayInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.CompressionLevel;
public class ZipTest {
public static void main(String[] args) throws Exception {
String zipFileName = "big-file.zip";
generateTestFile(zipFileName);
addComment(zipFileName);
// net.lingala.zip4j.exception.ZipException: invalid signature for zip64 end of central directory record
readZipFile(zipFileName);
}
private static void generateTestFile(String fileName) throws Exception {
Files.deleteIfExists(Paths.get(fileName));
byte[] data = new byte[1024 * 1024 * 1024];
Arrays.fill(data, (byte) 0);
ZipParameters commonParams = new ZipParameters();
commonParams.setCompressionLevel(CompressionLevel.NO_COMPRESSION);
try (ZipFile zipFile = new ZipFile(fileName)) {
for (int i = 0; i < 5; i++) {
ZipParameters entryParam = new ZipParameters(commonParams);
entryParam.setFileNameInZip("file-" + i + ".dat");
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
zipFile.addStream(inputStream, entryParam);
}
}
}
private static void addComment(String fileName) throws Exception {
try (ZipFile zipFile = new ZipFile(fileName)) {
zipFile.setComment("comment");
}
}
private static void readZipFile(String fileName) throws Exception {
try (ZipFile zipFile = new ZipFile(fileName)) {
// net.lingala.zip4j.exception.ZipException: invalid signature for zip64 end of central directory record
List<FileHeader> fileHeaders = zipFile.getFileHeaders();
for (FileHeader fileHeader : fileHeaders) {
System.out.println(fileHeader.getFileName());
}
}
}
}
I checked the generated files using the command unzip -t big-file.zip
and the output was as follows.
Archive: big-file.zip
comment
error: End-of-centdir-64 signature not where expected (prepended bytes?)
(attempting to process anyway)
warning [big-file.zip]: 1074561330 extra bytes at beginning or within zipfile
(attempting to process anyway)
file #1: bad zipfile offset (local header sig): 1074561330
(attempting to re-compensate)
testing: file-0.dat OK
testing: file-1.dat OK
testing: file-2.dat OK
testing: file-3.dat OK
testing: file-4.dat OK
At least one error was detected in big-file.zip.
The output of command zip -FF big-file.zip --out big-file-fix.zip
was as follows.
Fix archive (-FF) - salvage what can
Found end record (EOCDR) - says expect single disk archive
Found archive comment
Scanning for entries...
copying: file-0.dat (1073905669 bytes)
copying: file-1.dat (1073905669 bytes)
copying: file-2.dat (1073905669 bytes)
copying: file-3.dat (1073905669 bytes)
copying: file-4.dat (1073905669 bytes)
Central Directory found...
Zip64 EOCDR found ( 1 5369528937)...
Zip64 EOCDL found ( 1 5369528993)...
EOCDR found ( 1 5369529013)...