App-zipdetails

 view release on metacpan or  search on metacpan

bin/zipdetails  view on Meta::CPAN

            # Auto-generate getter/setter
            *$method = sub  {
                $_[0]->{$name} = $_[1]
                    if @_ == 2;
                return $_[0]->{$name} ;
            }
            unless defined $done->{$method};

            ++ $done->{$method};


        }
    }
}

{
    package BaseEntry ;

    sub new
    {
        my $class = shift ;

        state $index = 0;

        my %fields = (
                        'index'                 => $index ++,
                        'zip64'                 => 0,
                        'offsetStart'           => 0,
                        'offsetEnd'             => 0,
                        'inCentralDir'          => 0,
                        'encapsulated'          => 0, # enclosed in outer zip
                        'childrenCount'         => 0, # this entry is a zip with enclosed children
                        'streamed'              => 0,
                        'languageEncodingFlag'  => 0,
                        'entryType'             => 0,
                     ) ;

        my $self = bless {}, $class;

        FieldsAndAccessors::Add($class, $self, \%fields) ;

        return $self;
    }

    sub increment_childrenCount
    {
        my $self = shift;
        $self->{childrenCount} ++;
    }
}

{
    package LocalCentralEntryBase ;

    use parent -norequire , 'BaseEntry' ;

    sub new
    {
        my $class = shift ;

        my $self = $class->SUPER::new();


        my %fields = (
                        # fields from the header
                        'centralHeaderOffset'   => 0,
                        'localHeaderOffset'     => 0,

                        'extractVersion'        => 0,
                        'generalPurposeFlags'   => 0,
                        'compressedMethod'      => 0,
                        'lastModDateTime'       => 0,
                        'crc32'                 => 0,
                        'compressedSize'        => 0,
                        'uncompressedSize'      => 0,
                        'filename'              => '',
                        'outputFilename'        => '',
                        # inferred data
                        # 'InCentralDir'          => 0,
                        # 'zip64'                 => 0,

                        'zip64ExtraPresent'     => 0,
                        'zip64SizesPresent'     => 0,
                        'payloadOffset'         => 0,

                        # zip64 extra
                        'zip64_compressedSize'    => undef,
                        'zip64_uncompressedSize'  => undef,
                        'zip64_localHeaderOffset' => undef,
                        'zip64_diskNumber'        => undef,
                        'zip64_diskNumberPresent' => 0,

                        # Values direct from the header before merging any Zip64 values
                        'std_compressedSize'    => undef,
                        'std_uncompressedSize'  => undef,
                        'std_localHeaderOffset' => undef,
                        'std_diskNumber'        => undef,

                        # AES
                        'aesStrength'             => 0,
                        'aesValid'                => 0,

                        # Minizip CD encryption
                        'minizip_secure'          => 0,

                     ) ;

        FieldsAndAccessors::Add($class, $self, \%fields) ;

        return $self;
    }
}

{
    package Zip64EndCentralHeaderEntry ;

    use parent -norequire , 'LocalCentralEntryBase' ;

    sub new
    {
        my $class = shift ;

        my $self = $class->SUPER::new();


        my %fields = (
                        'inCentralDir'          => 1,
                     ) ;

        FieldsAndAccessors::Add($class, $self, \%fields) ;

        return $self;
    }

}

{
    package CentralDirectoryEntry;

    use parent -norequire , 'LocalCentralEntryBase' ;

    use constant Offset_VersionMadeBy           => 4;
    use constant Offset_VersionNeededToExtract  => 6;
    use constant Offset_GeneralPurposeFlags     => 8;
    use constant Offset_CompressionMethod       => 10;
    use constant Offset_ModificationTime        => 12;
    use constant Offset_ModificationDate        => 14;
    use constant Offset_CRC32                   => 16;
    use constant Offset_CompressedSize          => 20;
    use constant Offset_UncompressedSize        => 24;
    use constant Offset_FilenameLength          => 28;
    use constant Offset_ExtraFieldLength        => 30;
    use constant Offset_FileCommentLength       => 32;
    use constant Offset_DiskNumber              => 34;
    use constant Offset_InternalAttributes      => 36;
    use constant Offset_ExternalAttributes      => 38;
    use constant Offset_RelativeOffsetToLocal   => 42;
    use constant Offset_Filename                => 46;

    sub new
    {
        my $class = shift ;
        my $offset = shift;

        # check for existing entry
        return $CentralDirectory->{byCentralOffset}{$offset}
            if defined $offset && defined $CentralDirectory->{byCentralOffset}{$offset} ;

        my $self = $class->SUPER::new();

        my %fields = (
                        'diskNumber'                => 0,
                        'comment'                   => "",
                        'ldEntry'                   => undef,
                     ) ;

        FieldsAndAccessors::Add($class, $self, \%fields) ;

        $self->inCentralDir(1) ;
        $self->entryType(::ZIP_CENTRAL_HDR_SIG) ;

        return $self;
    }
}

{
    package CentralDirectory;

    sub new
    {
        my $class = shift ;

        my %object = (
                        'entries'       => [],
                        'count'         => 0,
                        'byLocalOffset' => {},
                        'byCentralOffset' => {},
                        'byName'        => {},
                        'offset2Index' => {},
                        'normalized_filenames' => {},
                        'CentralDirectoryOffset'      => 0,
                        'CentralDirectorySize'      => 0,
                        'zip64'         => 0,
                        'encryptedCD'   => 0,
                        'minizip_secure' => 0,
                        'alreadyScanned' => 0,
                     ) ;

        bless \%object, $class;
    }

    sub addEntry
    {
        my $self = shift ;
        my $entry = shift ;

        my $localHeaderOffset = $entry->localHeaderOffset  ;
        my $CentralDirectoryOffset = $entry->centralHeaderOffset ;
        my $filename = $entry->filename ;

        Nesting::add($entry);

        # Create a reference from Central to Local header entries
        my $ldEntry = Nesting::getLdEntryByOffset($localHeaderOffset);
        if ($ldEntry)
        {
            $entry->ldEntry($ldEntry) ;

            # LD -> CD

bin/zipdetails  view on Meta::CPAN

        $self->{minizip_secure} = 1 ;
    }

    sub isMiniZipEncrypted
    {
        my $self = shift ;
        return $self->{minizip_secure};
    }

    sub isEncryptedCD
    {
        my $self = shift ;
        return $self->{encryptedCD} && ! $self->{minizip_secure};
    }

    sub normalize_filename
    {
        # check if there is a filename that already exists
        # with the same name when normalized to lower case

        my $self = shift ;
        my $entry = shift;
        my $filename = shift;

        my $nFilename = lc $filename;

        my $lookup = $self->{normalized_filenames}{$nFilename};
        # if ($lookup && $lookup ne $filename)
        if ($lookup)
        {
            return $lookup,
        }

        $self->{normalized_filenames}{$nFilename} = $entry;

        return undef;
    }
}

{
    package LocalDirectoryEntry;

    use parent -norequire , 'LocalCentralEntryBase' ;

    use constant Offset_VersionNeededToExtract  => 4;
    use constant Offset_GeneralPurposeFlags     => 6;
    use constant Offset_CompressionMethod       => 8;
    use constant Offset_ModificationTime        => 10;
    use constant Offset_ModificationDate        => 12;
    use constant Offset_CRC32                   => 14;
    use constant Offset_CompressedSize          => 18;
    use constant Offset_UncompressedSize        => 22;
    use constant Offset_FilenameLength          => 26;
    use constant Offset_ExtraFieldLength        => 27;
    use constant Offset_Filename                => 30;

    sub new
    {
        my $class = shift ;

        my $self = $class->SUPER::new();

        my %fields = (
                        'streamedMatch'         => 0,
                        'readDataDescriptor'    => 0,
                        'cdEntryIndex'          => {},
                        'cdEntryList'           => [],
                     ) ;

        FieldsAndAccessors::Add($class, $self, \%fields) ;

        $self->inCentralDir(0) ;
        $self->entryType(::ZIP_LOCAL_HDR_SIG) ;

        return $self;
    }

    sub addCdEntry
    {
        my $self = shift ;
        my $entry = shift;

        # don't want encapsulated entries
        # and protect against duplicates
        return
            if $entry->encapsulated ||
               $self->{cdEntryIndex}{$entry->index} ++ >= 1;

        push @{ $self->{cdEntryList} }, $entry ;
    }

    sub getCdEntry
    {
        my $self = shift ;

        return []
            if ! $self->{cdEntryList} ;

        return $self->{cdEntryList}[0] ;
    }

    sub getCdEntries
    {
        my $self = shift ;
        return $self->{cdEntryList} ;
    }
}

{
    package LocalDirectory;

    sub new
    {
        my $class = shift ;

        my %object = (
                        'entries'       => [],
                        'count'         => 0,
                        'byLocalOffset' => {},
                        'byName'        => {},
                        'offset2Index' => {},



( run in 1.695 second using v1.01-cache-2.11-cpan-b16cb0d3907 )