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 )