srikanth-lingala / zip4j

A Java library for zip files and streams
Apache License 2.0
2.06k stars 310 forks source link

Adding a file to an existing zip can lead to corruption of the zip file #498

Open liufengwenyu opened 1 year ago

liufengwenyu commented 1 year ago

A zip file has a data descriptor, and when a new file is added, there will be additional data at the end of the zip file. image struct ZIPDIRENTRY dirEntry[341] is the new file struct ZIPENDLOCATOR endLocator[0] is the End of central directory record of the new zip struct ZIPDIRENTRY dirEntry[342] is the is the last file of the old zip struct ZIPENDLOCATOR endLocator[1] is the End of central directory record of the old zip struct ZIPDIRENTRY dirEntry[342] and struct ZIPENDLOCATOR endLocator[1] are redundant

Below is my code

net.lingala.zip4j.ZipFile zipFile = null;
try {
    zipFile = new ZipFile(args[0]);
    ZipParameters parameters = new ZipParameters();
    parameters.setCompressionMethod(CompressionMethod.DEFLATE);
    parameters.setCompressionLevel(CompressionLevel.NORMAL);
    parameters.setFileNameInZip("assets/neoptionBin");
    zipFile.addFile(info, parameters);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    try {
        if (zipFile != null) {
            zipFile.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
srikanth-lingala commented 1 year ago

Which version of zip file are you using? I was unable to reproduce this issue. When I added a file to an existing zip file, I got the right output. Below are some screenshots:

image

image

srikanth-lingala commented 1 year ago

And I see in your screenshot that there are two entries in the zip file with the same filename META-INF/CERT.RSA. This shouldn't have been the case if the file was added by zip4j. Zip4j replaces a file if an entry in zip exists already with the same name that you are adding.

liufengwenyu commented 1 year ago

I'm using version 2.11.5 and I'm sorry I can't upload my sample because it's over 25M. The difference between it and other normal zips is that it has a data descriptor area, as shown in the image below image When the file is added, the last bit of the original zip file is preserved as if the buffer was not truncated.

liufengwenyu commented 1 year ago

Another strange thing is that when I use 7zip to arbitrarily delete a file from the original zip, and then use zip4j to add the file, it behaves normally.