App-zipdetails
view release on metacpan or search on metacpan
bin/zipdetails view on Meta::CPAN
# See https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
# and https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-smb/65e0c225-5925-44b0-8104-6b91339c709f
out1 "[Bit 0]", "Read-Only" if $dos_attrib & WIN_FILE_ATTRIBUTE_READONLY ;
out1 "[Bit 1]", "Hidden" if $dos_attrib & WIN_FILE_ATTRIBUTE_HIDDEN ;
out1 "[Bit 2]", "System" if $dos_attrib & WIN_FILE_ATTRIBUTE_SYSTEM ;
out1 "[Bit 3]", "Unused" if $dos_attrib & WIN_FILE_ATTRIBUTE_LABEL ; # bit not used
out1 "[Bit 4]", "Directory" if $dos_attrib & WIN_FILE_ATTRIBUTE_DIRECTORY ;
out1 "[Bit 5]", "Archive" if $dos_attrib & WIN_FILE_ATTRIBUTE_ARCHIVE ;
out1 "[Bit 6]", "Device/Symbolic Link" if $dos_attrib & WIN_FILE_ATTRIBUTE_DEVICE_OR_SYMBOLIC_LINK ; # Tentative use of Symbolic Link.
out1 "[Bit 7]", "Normal/Executable" if $dos_attrib & WIN_FILE_ATTRIBUTE_NORMAL_OR_EXECUTABLE ; # Tentative use of Executable
out1 "[Bit 8]", "Temporary" if $dos_attrib & WIN_FILE_ATTRIBUTE_TEMPORARY ;
out1 "[Bit 9]", "Sparse" if $dos_attrib & WIN_FILE_ATTRIBUTE_SPARSE_FILE ;
out1 "[Bit 10]", "Reparse Point" if $dos_attrib & WIN_FILE_ATTRIBUTE_REPARSE_POINT ;
out1 "[Bit 11]", "Compressed" if $dos_attrib & WIN_FILE_ATTRIBUTE_COMPRESSED ;
out1 "[Bit 12]", "Offline" if $dos_attrib & WIN_FILE_ATTRIBUTE_OFFLINE ;
out1 "[Bit 13]", "Not Indexed" if $dos_attrib & WIN_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED ;
# Zip files created on Mac seem to set this bit. Not reason why found yet.
out1 "[Bit 14]", "Encrypted" if $dos_attrib & WIN_FILE_ATTRIBUTE_ENCRYPTED ;
# p7Zip & 7z set this bit to flag that the high 16-bits are Unix attributes
out1 "[Bit 15]", "Possible p7zip/7z Unix Flag" if $dos_attrib & 0x8000 ;
}
my $native_attrib = ($ext_file_attrib >> 16 ) & 0xFFFF;
# Some Windows zip file (created OS == 0), have th eUnix attributes populated.
if ($made_by == 3 || $made_by == 0) # Unix
{
state $mask = {
0 => '---',
1 => '--x',
2 => '-w-',
3 => '-wx',
4 => 'r--',
5 => 'r-x',
6 => 'rw-',
7 => 'rwx',
} ;
my $rwx = ($native_attrib & 0777);
if ($rwx)
{
my $output = '';
$output .= $mask->{ ($rwx >> 6) & 07 } ;
$output .= $mask->{ ($rwx >> 3) & 07 } ;
$output .= $mask->{ ($rwx >> 0) & 07 } ;
out1 "[Bits 16-24]", Value_v($rwx) . " 'Unix attrib: $output'" ;
out1 "[Bit 25]", "1 'Sticky'"
if $rwx & 0x200 ;
out1 "[Bit 26]", "1 'Set GID'"
if $rwx & 0x400 ;
out1 "[Bit 27]", "1 'Set UID'"
if $rwx & 0x800 ;
my $not_rwx = (($native_attrib >> 12) & 0xF);
if ($not_rwx)
{
state $masks = {
0x0C => 'Socket', # 0x0C 0b1100
0x0A => 'Symbolic Link', # 0x0A 0b1010
0x08 => 'Regular File', # 0x08 0b1000
0x06 => 'Block Device', # 0x06 0b0110
0x04 => 'Directory', # 0x04 0b0100
0x02 => 'Character Device', # 0x02 0b0010
0x01 => 'FIFO', # 0x01 0b0001
};
my $got = $masks->{$not_rwx} // 'Unknown Unix attrib' ;
out1 "[Bits 28-31]", Value_C($not_rwx) . " '$got'"
}
}
}
elsif ($native_attrib)
{
out1 "[Bits 24-31]", Value_v($native_attrib) . " 'Unknown attributes for OS ID $made_by'"
}
my ($d, $locHeaderOffset) = read_V();
my $out = Value_V($locHeaderOffset);
my $std_localHeaderOffset = $locHeaderOffset;
if ($locHeaderOffset != MAX32)
{
testPossiblePrefix($locHeaderOffset, ZIP_LOCAL_HDR_SIG);
if ($PREFIX_DELTA)
{
$out .= " [Actual Offset is " . Value_V($locHeaderOffset + $PREFIX_DELTA) . "]"
}
}
out $d, "Local Header Offset", $out;
if ($locHeaderOffset != MAX32)
{
my $commonMessage = "'Local Header Offset' field in '" . Signatures::name($signature) . "' is invalid";
$locHeaderOffset = checkOffsetValue($locHeaderOffset, $startRecordOffset, 0, $commonMessage, $startRecordOffset + CentralDirectoryEntry::Offset_RelativeOffsetToLocal(), ZIP_LOCAL_HDR_SIG) ;
}
my $filename = '';
if ($filenameLength)
{
need $filenameLength, Signatures::name($signature), 'Filename';
myRead(my $raw_filename, $filenameLength);
$cdEntry->filename($raw_filename) ;
$filename = outputFilename($raw_filename, $LanguageEncodingFlag);
$cdEntry->outputFilename($filename);
}
$cdEntry->centralHeaderOffset($cdEntryOffset) ;
$cdEntry->localHeaderOffset($locHeaderOffset) ;
$cdEntry->compressedSize($compressedSize) ;
$cdEntry->uncompressedSize($uncompressedSize) ;
$cdEntry->zip64ExtraPresent(undef) ; #$cdZip64; ### FIX ME
$cdEntry->zip64SizesPresent(undef) ; # $zip64Sizes; ### FIX ME
$cdEntry->extractVersion($extractVer);
$cdEntry->generalPurposeFlags($gpFlag);
$cdEntry->compressedMethod($compressedMethod) ;
$cdEntry->lastModDateTime($lastMod);
$cdEntry->crc32($crc) ;
$cdEntry->inCentralDir(1) ;
$cdEntry->std_localHeaderOffset($std_localHeaderOffset) ;
$cdEntry->std_compressedSize($std_compressedSize) ;
$cdEntry->std_uncompressedSize($std_uncompressedSize) ;
$cdEntry->std_diskNumber($std_disk_start) ;
if ($extraLength)
{
bin/zipdetails view on Meta::CPAN
# APPNOTE 6.3.10, sec 4.6.9
my $extraID = shift ;
my $len = shift;
my $entry = shift;
out_C " Version";
out_V " NameCRC32";
if ($len - 5 > 0)
{
myRead(my $data, $len - 5);
outputFilename($data, 1, " UnicodeName");
}
}
sub decode_ASi_Unix
{
my $extraID = shift ;
my $len = shift;
my $entry = shift;
# https://stackoverflow.com/questions/76581811/why-does-unzip-ignore-my-zip64-end-of-central-directory-record
out_V " CRC";
my $native_attrib = out_v " Mode";
# TODO - move to separate sub & tidy
if (1) # Unix
{
state $mask = {
0 => '---',
1 => '--x',
2 => '-w-',
3 => '-wx',
4 => 'r--',
5 => 'r-x',
6 => 'rw-',
7 => 'rwx',
} ;
my $rwx = ($native_attrib & 0777);
if ($rwx)
{
my $output = '';
$output .= $mask->{ ($rwx >> 6) & 07 } ;
$output .= $mask->{ ($rwx >> 3) & 07 } ;
$output .= $mask->{ ($rwx >> 0) & 07 } ;
out1 " [Bits 0-8]", Value_v($rwx) . " 'Unix attrib: $output'" ;
out1 " [Bit 9]", "1 'Sticky'"
if $rwx & 0x200 ;
out1 " [Bit 10]", "1 'Set GID'"
if $rwx & 0x400 ;
out1 " [Bit 11]", "1 'Set UID'"
if $rwx & 0x800 ;
my $not_rwx = (($native_attrib >> 12) & 0xF);
if ($not_rwx)
{
state $masks = {
0x0C => 'Socket', # 0x0C 0b1100
0x0A => 'Symbolic Link', # 0x0A 0b1010
0x08 => 'Regular File', # 0x08 0b1000
0x06 => 'Block Device', # 0x06 0b0110
0x04 => 'Directory', # 0x04 0b0100
0x02 => 'Character Device', # 0x02 0b0010
0x01 => 'FIFO', # 0x01 0b0001
};
my $got = $masks->{$not_rwx} // 'Unknown Unix attrib' ;
out1 " [Bits 12-15]", Value_C($not_rwx) . " '$got'"
}
}
}
my $s = out_V " SizDev";
out_v " UID";
out_v " GID";
}
sub decode_uc
{
# APPNOTE 6.3.10, sec 4.6.8
my $extraID = shift ;
my $len = shift;
my $entry = shift;
out_C " Version";
out_V " ComCRC32";
if ($len - 5 > 0)
{
myRead(my $data, $len - 5);
outputFilename($data, 1, " UnicodeCom");
}
}
sub decode_Xceed_unicode
{
# 0x554e
my $extraID = shift ;
my $len = shift;
my $entry = shift;
my $data ;
my $remaining = $len;
# No public definition available, so reverse engineer the content.
# See https://github.com/pmqs/zipdetails/issues/13 for C# source that populates
# this field.
# Fiddler https://www.telerik.com/fiddler) creates this field.
# Local Header only has UTF16LE filename
#
# Field definition
# 4 bytes Signature always XCUN
# 2 bytes Filename Length (divided by 2)
# Filename
# Central has UTF16LE filename & comment
#
# Field definition
# 4 bytes Signature always XCUN
# 2 bytes Filename Length (divided by 2)
( run in 1.214 second using v1.01-cache-2.11-cpan-9581c071862 )