diff --git a/bin/zipdetails b/bin/zipdetails index 4a17256..e3a8540 100755 --- a/bin/zipdetails +++ b/bin/zipdetails @@ -4157,6 +4157,11 @@ sub walk_Zip64_in_LD $entry->uncompressedSize(unpack "Q<", $data); out2 $data, "Uncompressed Size", Value_Q($entry->uncompressedSize) if $display; + if (! full32 $entry->std_uncompressedSize) + { + info $data, "Uncompressed Size should not be present in the ZIP64 extra field. Corresponding uncompressedSize from local header is not set to 0xFFFFFFFF, value is " . Value_V($entry->uncompressedSize) + if $display; + } } if ($assumeLengthsPresent || $assumeAllFieldsPresent || full32 $entry->std_compressedSize) @@ -4175,6 +4180,11 @@ sub walk_Zip64_in_LD $entry->compressedSize( unpack "Q<", $data); out2 $data, "Compressed Size", Value_Q($entry->compressedSize) if $display; + if (! full32 $entry->std_compressedSize) + { + info $data, "Compressed Size should not be present in the ZIP64 extra field. Corresponding compressedSize from local header is not set to 0xFFFFFFFF, value is " . Value_V($entry->compressedSize) + if $display; + } } # Zip64 in local header should not have localHeaderOffset or disk number @@ -4188,6 +4198,11 @@ sub walk_Zip64_in_LD my $localHeaderOffset = unpack "Q<", $data; out2 $data, "Offset to Local Dir", Value_Q($localHeaderOffset) if $display; + if (! full32 $entry->std_localHeaderOffset) + { + info $data, "Offset to Local Dir should not be present in the ZIP64 extra field. Value is " . Value_V($entry->localHeaderOffset) + if $display; + } } if ($assumeAllFieldsPresent) @@ -4198,6 +4213,11 @@ sub walk_Zip64_in_LD my $diskNumber = unpack "v", $data; out2 $data, "Disk Number", Value_V($diskNumber) if $display; + if (! full16 $entry->std_diskNumber) + { + info $data, "Disk Number should not be present in the ZIP64 extra field. Value is " . Value_V($entry->diskNumber) + if $display; + } } if (length $zip64Extended) @@ -4230,9 +4250,13 @@ sub walk_Zip64_in_CD return; } - my $assumeAllFieldsPresent = (length($zip64Extended) == 28) ; + # The order of the fields in the zip64 extended + # information record is fixed, but the fields MUST + # only appear if the corresponding Local or Central + # directory record field is set to 0xFFFF or 0xFFFFFFFF. + my $assumeAllFieldsPresent = (length($zip64Extended) == 28); - if ($assumeAllFieldsPresent || full32 $entry->std_uncompressedSize ) + if ($assumeAllFieldsPresent || full32 $entry->std_uncompressedSize) { if (length $zip64Extended < 8) { @@ -4247,6 +4271,11 @@ sub walk_Zip64_in_CD $entry->uncompressedSize(unpack "Q<", $data); out2 $data, "Uncompressed Size", Value_Q($entry->uncompressedSize) if $display; + if (! full32 $entry->std_uncompressedSize) + { + info $data, "Uncompressed Size should not be present in the ZIP64 extra field. Corresponding uncompressedSize from central header is not set to 0xFFFFFFFF, value is " . Value_V($entry->uncompressedSize) + if $display; + } } if ($assumeAllFieldsPresent || full32 $entry->std_compressedSize) @@ -4265,6 +4294,11 @@ sub walk_Zip64_in_CD $entry->compressedSize(unpack "Q<", $data); out2 $data, "Compressed Size", Value_Q($entry->compressedSize) if $display; + if (! full32 $entry->std_compressedSize) + { + info $data, "Compressed Size should not be present in the ZIP64 extra field. Corresponding compressedSize from central header is not set to 0xFFFFFFFF, value is " . Value_V($entry->compressedSize) + if $display; + } } if ($assumeAllFieldsPresent || full32 $entry->std_localHeaderOffset) @@ -4279,7 +4313,6 @@ sub walk_Zip64_in_CD $fieldOffset += 8; - my $here = $FH->tell(); my $data = substr($zip64Extended, 0, 8, "") ; $entry->localHeaderOffset(unpack "Q<", $data); out2 $data, "Offset to Local Dir", Value_Q($entry->localHeaderOffset) @@ -4287,13 +4320,18 @@ sub walk_Zip64_in_CD my $commonMessage = "'Offset to Local Dir' field in 'Zip64 Extra Field' is invalid"; $entry->localHeaderOffset(checkOffsetValue($entry->localHeaderOffset, $fieldStart, 0, $commonMessage, $fieldStart, ZIP_LOCAL_HDR_SIG, 0) ); + if (! full32 $entry->std_localHeaderOffset) + { + info $data, "Offset to Local Dir should not be present in the ZIP64 extra field. Corresponding localHeaderOffset from central header is not set to 0xFFFFFFFF, value is " . Value_V($entry->localHeaderOffset) + if $display; + } } if ($assumeAllFieldsPresent || full16 $entry->std_diskNumber) { if (length $zip64Extended < 4) { - my $message = extraFieldIdentifier($extraID) . ": Expected " . decimalHex0x(4) . " bytes for 'Disk Number': only " . decimalHex0x(length $zip64Extended) . " bytes present"; + my $message = extraFieldIdentifier($extraID) . ": Expected " . decimalHex0x(4) . " bytes for 'Disk Number': only " . decimalHex0x(length $zip64Extended) . " bytes present"; error $fieldOffset, $message; out2 $zip64Extended, $message; return; @@ -4301,12 +4339,16 @@ sub walk_Zip64_in_CD $fieldOffset += 4; - my $here = $FH->tell(); my $data = substr($zip64Extended, 0, 4, "") ; $entry->diskNumber(unpack "v", $data); out2 $data, "Disk Number", Value_V($entry->diskNumber) if $display; $entry->zip64_diskNumberPresent(1); + if (! full16 $entry->std_diskNumber) + { + info $data, "Disk Number should not be present in the ZIP64 extra field. Corresponding diskNumber from central header is not set to 0xFFFF, value is " . Value_V($entry->diskNumber) + if $display; + } } if (length $zip64Extended)