App-zipdetails
view release on metacpan or search on metacpan
bin/zipdetails view on Meta::CPAN
my $diskNumber = unpack("v", substr($buffer, 34, 2));
my $locHeaderOffset = unpack("V", substr($buffer, 42, 4));
my $cdZip64 = 0;
my $zip64Sizes = 0;
if (! full32 $locHeaderOffset)
{
# Check for corrupt offset
# 1. pointing paset EOF
# 2. offset points forward in the file
# 3. value at offset is not a CD record signature
my $commonMessage = "'Local Header Offset' field in '" . Signatures::name(ZIP_CENTRAL_HDR_SIG) . "' is invalid";
checkOffsetValue($locHeaderOffset, $startHeader, 0, $commonMessage,
$startHeader + CentralDirectoryEntry::Offset_RelativeOffsetToLocal(),
ZIP_LOCAL_HDR_SIG, 1) ;
}
$fh->read(my $filename, $filename_length) ;
my $cdEntry = CentralDirectoryEntry->new();
$cdEntry->centralHeaderOffset($startHeader) ;
$cdEntry->localHeaderOffset($locHeaderOffset) ;
$cdEntry->compressedSize($compressedSize) ;
$cdEntry->uncompressedSize($uncompressedSize) ;
$cdEntry->extractVersion($extractVer);
$cdEntry->generalPurposeFlags($gpFlag);
$cdEntry->filename($filename) ;
$cdEntry->lastModDateTime($lastMod);
$cdEntry->languageEncodingFlag($gpFlag & ZIP_GP_FLAG_LANGUAGE_ENCODING) ;
$cdEntry->diskNumber($diskNumber) ;
$cdEntry->crc32($crc) ;
$cdEntry->zip64ExtraPresent($cdZip64) ;
$cdEntry->std_localHeaderOffset($locHeaderOffset) ;
$cdEntry->std_compressedSize($compressedSize) ;
$cdEntry->std_uncompressedSize($uncompressedSize) ;
$cdEntry->std_diskNumber($diskNumber) ;
if ($extra_length)
{
$fh->read(my $extraField, $extra_length) ;
# Check for Zip64
my $zip64Extended = findID(0x0001, $extraField);
if ($zip64Extended)
{
$cdZip64 = 1;
walk_Zip64_in_CD(1, $zip64Extended, $cdEntry, 0);
}
}
$cdEntry->offsetStart($startHeader) ;
$cdEntry->offsetEnd($FH->tell() - 1);
# don't call addEntry until after the extra fields have been scanned
# the localheader offset value may be updated in th ezip64 extra field.
$CentralDirectory->addEntry($cdEntry);
$HeaderOffsetIndex->addOffset($cdEntry->localHeaderOffset, ZIP_LOCAL_HDR_SIG) ;
skip($fh, $comment_length ) ;
}
$FH->seek($fh->tell() - ZIP_CD_FILENAME_OFFSET, SEEK_SET);
# Check for Digital Signature
$HeaderOffsetIndex->addOffset($fh->tell() - 4, ZIP_DIGITAL_SIGNATURE_SIG)
if $fh->read($buffer, 4) == 4 &&
unpack("V", $buffer) == ZIP_DIGITAL_SIGNATURE_SIG ;
$CentralDirectory->sortByLocalOffset();
$HeaderOffsetIndex->sortOffsets();
$fh->seek($here, SEEK_SET) ;
}
use constant ZIP64_END_CENTRAL_LOC_HDR_SIZE => 20;
use constant ZIP64_END_CENTRAL_REC_HDR_MIN_SIZE => 56;
sub offsetFromZip64
{
my $fh = shift ;
my $here = shift;
my $eocdSize = shift;
#### Zip64 end of central directory locator
# check enough bytes available for zip64 locator record
fatal_tryWalk undef, "Cannot find signature for " . Signatures::nameAndHex(ZIP64_END_CENTRAL_LOC_HDR_SIG), # 'Zip64 end of central directory locator': 0x07064b50"
"Possible truncated or corrupt zip file"
if $here < ZIP64_END_CENTRAL_LOC_HDR_SIZE ;
$fh->seek($here - ZIP64_END_CENTRAL_LOC_HDR_SIZE, SEEK_SET) ;
$here = $FH->tell();
my $buffer;
my $got = 0;
$fh->read($buffer, ZIP64_END_CENTRAL_LOC_HDR_SIZE);
my $gotSig = unpack("V", $buffer);
fatal_tryWalk $here - 4, sprintf("Expected signature for " . Signatures::nameAndHex(ZIP64_END_CENTRAL_LOC_HDR_SIG) . " not found, got 0x%X", $gotSig)
if $gotSig != ZIP64_END_CENTRAL_LOC_HDR_SIG ;
$HeaderOffsetIndex->addOffset($fh->tell() - ZIP64_END_CENTRAL_LOC_HDR_SIZE, ZIP64_END_CENTRAL_LOC_HDR_SIG) ;
my $cd64 = unpack "Q<", substr($buffer, 8, 8);
my $totalDisks = unpack "V", substr($buffer, 16, 4);
testPossiblePrefix($cd64, ZIP64_END_CENTRAL_REC_HDR_SIG);
if ($totalDisks > 0)
{
my $commonMessage = "'Offset to Zip64 End of Central Directory Record' field in '" . Signatures::name(ZIP64_END_CENTRAL_LOC_HDR_SIG) . "' is invalid";
$cd64 = checkOffsetValue($cd64, $here, 0, $commonMessage, $here + 8, ZIP64_END_CENTRAL_REC_HDR_SIG, 1) ;
}
( run in 0.927 second using v1.01-cache-2.11-cpan-5a3173703d6 )