2 Add the tl;dr.
source | link

Attempting to fix an archive will compare the local and central CRCs, and combining that with archive tests will allow all the CRCs to be checked. If you run

unzip -t archive.zip

Startingand

zip -F archive.zip --out archivefix.zip

and neither complain, that means the archive’s contents match both the central and local CRCs. (You can delete archivefix.zip afterwards.)

To verify this, starting with the Info-ZIP source code for zip 3.0, I created a file as follows:

zip -9 test.zip zip.txt zipup.c

I then corrupted the central directory CRC for zip.txt by changing the byte at offset 0xB137. I got the opposite behaviour to what you observed; unzip -v reported the altered CRC from the central directory, but unzip -t and zip -T reported that the file was OK (checking against the local CRC).

But running

zip -F test --out testfix

reported

Fix archive (-F) - assume mostly intact archive
Zip entry offsets do not need adjusting
 copying: zip.txt
        zip warning: Local Entry CRC does not match CD: zip.txt
 copying: zipup.c

The "corrected" file still listed the altered CRC for zip.txt.

Altering the local CRC for zip.txt at offset 0x10 caused both unzip -t and zip -T to report a CRC error, but zip -F didn't spot anything wrong.

Thus from my experiments, mismatches between an archive entry's contents and its CRCs can be detected as follows:

  • local only: zip -T and unzip -t; zip -F will also complain about the local-central mismatch
  • local and central: zip -T and unzip -t
  • central only: zip -T and unzip -t will not complain, but zip -F will indicate a local-central mismatch

(Note that by default zip -T simply uses unzip -tqq, so zip -T and unzip -t really are equivalent. You can read the unzip source code to check that testing an archive really compares the local CRC, not the central one; look for extract_or_test_files(), extract_or_test_entrylist() and extract_or_test_member(), all in extract.c.)

Attempting to fix an archive will compare the local and central CRCs, and combining that with archive tests will allow all the CRCs to be checked.

Starting with the Info-ZIP source code for zip 3.0, I created a file as follows:

zip -9 test.zip zip.txt zipup.c

I then corrupted the central directory CRC for zip.txt by changing the byte at offset 0xB137. I got the opposite behaviour to what you observed; unzip -v reported the altered CRC from the central directory, but unzip -t and zip -T reported that the file was OK (checking against the local CRC).

But running

zip -F test --out testfix

reported

Fix archive (-F) - assume mostly intact archive
Zip entry offsets do not need adjusting
 copying: zip.txt
        zip warning: Local Entry CRC does not match CD: zip.txt
 copying: zipup.c

The "corrected" file still listed the altered CRC for zip.txt.

Altering the local CRC for zip.txt at offset 0x10 caused both unzip -t and zip -T to report a CRC error, but zip -F didn't spot anything wrong.

Thus from my experiments, mismatches between an archive entry's contents and its CRCs can be detected as follows:

  • local only: zip -T and unzip -t; zip -F will also complain about the local-central mismatch
  • local and central: zip -T and unzip -t
  • central only: zip -T and unzip -t will not complain, but zip -F will indicate a local-central mismatch

(Note that by default zip -T simply uses unzip -tqq, so zip -T and unzip -t really are equivalent. You can read the unzip source code to check that testing an archive really compares the local CRC, not the central one; look for extract_or_test_files(), extract_or_test_entrylist() and extract_or_test_member(), all in extract.c.)

Attempting to fix an archive will compare the local and central CRCs, and combining that with archive tests will allow all the CRCs to be checked. If you run

unzip -t archive.zip

and

zip -F archive.zip --out archivefix.zip

and neither complain, that means the archive’s contents match both the central and local CRCs. (You can delete archivefix.zip afterwards.)

To verify this, starting with the Info-ZIP source code for zip 3.0, I created a file as follows:

zip -9 test.zip zip.txt zipup.c

I then corrupted the central directory CRC for zip.txt by changing the byte at offset 0xB137. I got the opposite behaviour to what you observed; unzip -v reported the altered CRC from the central directory, but unzip -t and zip -T reported that the file was OK (checking against the local CRC).

But running

zip -F test --out testfix

reported

Fix archive (-F) - assume mostly intact archive
Zip entry offsets do not need adjusting
 copying: zip.txt
        zip warning: Local Entry CRC does not match CD: zip.txt
 copying: zipup.c

The "corrected" file still listed the altered CRC for zip.txt.

Altering the local CRC for zip.txt at offset 0x10 caused both unzip -t and zip -T to report a CRC error, but zip -F didn't spot anything wrong.

Thus from my experiments, mismatches between an archive entry's contents and its CRCs can be detected as follows:

  • local only: zip -T and unzip -t; zip -F will also complain about the local-central mismatch
  • local and central: zip -T and unzip -t
  • central only: zip -T and unzip -t will not complain, but zip -F will indicate a local-central mismatch

(Note that by default zip -T simply uses unzip -tqq, so zip -T and unzip -t really are equivalent. You can read the unzip source code to check that testing an archive really compares the local CRC, not the central one; look for extract_or_test_files(), extract_or_test_entrylist() and extract_or_test_member(), all in extract.c.)

1
source | link

Attempting to fix an archive will compare the local and central CRCs, and combining that with archive tests will allow all the CRCs to be checked.

Starting with the Info-ZIP source code for zip 3.0, I created a file as follows:

zip -9 test.zip zip.txt zipup.c

I then corrupted the central directory CRC for zip.txt by changing the byte at offset 0xB137. I got the opposite behaviour to what you observed; unzip -v reported the altered CRC from the central directory, but unzip -t and zip -T reported that the file was OK (checking against the local CRC).

But running

zip -F test --out testfix

reported

Fix archive (-F) - assume mostly intact archive
Zip entry offsets do not need adjusting
 copying: zip.txt
        zip warning: Local Entry CRC does not match CD: zip.txt
 copying: zipup.c

The "corrected" file still listed the altered CRC for zip.txt.

Altering the local CRC for zip.txt at offset 0x10 caused both unzip -t and zip -T to report a CRC error, but zip -F didn't spot anything wrong.

Thus from my experiments, mismatches between an archive entry's contents and its CRCs can be detected as follows:

  • local only: zip -T and unzip -t; zip -F will also complain about the local-central mismatch
  • local and central: zip -T and unzip -t
  • central only: zip -T and unzip -t will not complain, but zip -F will indicate a local-central mismatch

(Note that by default zip -T simply uses unzip -tqq, so zip -T and unzip -t really are equivalent. You can read the unzip source code to check that testing an archive really compares the local CRC, not the central one; look for extract_or_test_files(), extract_or_test_entrylist() and extract_or_test_member(), all in extract.c.)