Archive-Zip

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

    - Some cleaning up of the POD documentation for readability
    - Added SUPPORT section to docs
    - Merged external TODO file into the POD as a more-common TO DO section
    - Added a BUGS section to the docs

1.17_01 Sun 30 Apr 2006 - Adam Kennedy
    - Imported Archive::Zip into http://svn.ali.as/cpan/ orphanage.
      If you have a CPAN login and have released a module, ask ADAMK about an
      account and you can repair your bug directly in the repository.
    - Removed the revision comments from the old CVS repository
    - DOS DateTime Format doesn't support dates before 1980 and goes crazy when
      decoding back to unix time. If we don't get passed a time at all
      (0 or undef) we now throw an error.
    - DOS DateTime Format doesn't support dates before 1980, so if we find any
      we warn and use Jan 1 12:01pm 1980 if we encounter any
    - Win32 doesn't support directory modification times.
      Tentatively use the current time as the mod-time to prevent sending
      null times to the unix2dos converter (and the resulting error)
    - Reformat the expected empty zip warning in the output to add a note that
      the warning is entirely normal. Would be nice if some time later we can
      suppress it altogether, but I don't have the cross-platform STDERR-fu
      without adding a dependency to IPC::Run3 (which would be bad).
    - Adding a proper $VERSION to all classes, and synchronising them to the
      same value.

Changes  view on Meta::CPAN

    - Fixed errors with making directories in extractMember() when none provided
    - Return AZ_OK in extractMemberWithoutPaths() if member is a directory
    - Fixed problem in extractTree with blank directory becoming "." prefix
    - Added examples/writeScalar2.pl to show how to use IO::String as destination of Zip write
    - Edited docs and FAQ to recommend against using absolute path names in zip files.

1.05 Wed Sep 11 12:31:20 PDT 2002
    - fixed untaint from 1.04

1.04 Wed Sep 11 07:22:04 PDT 2002
    - added untaint of lastModFileDateTime

1.03 Mon Sep  2 20:42:43 PDT 2002
    - Removed dependency on IO::Scalar
    - Set required version of File::Spec to 0.8
    - Removed tests of examples that needed IO::Scalar
    - Added binmode() call to read/writeScalar examples
    - Fixed addTree() for 5.005 compatibility (still untested with 5.004)
    - Fixed mkdir() calls for 5.005
    - Clarified documentation of tree operations

lib/Archive/Zip.pm  view on Meta::CPAN


Return the member's external file name, if any, or undef.

=item fileName()

Get or set the member's internal filename. Returns the
(possibly new) filename. Names will have backslashes
converted to forward slashes, and will have multiple
consecutive slashes converted to single ones.

=item lastModFileDateTime()

Return the member's last modification date/time stamp in
MS-DOS format.

=item lastModTime()

Return the member's last modification date/time stamp,
converted to unix localtime format.

    print "Mod Time: " . scalar( localtime( $member->lastModTime() ) );

=item setLastModFileDateTimeFromUnix()

Set the member's lastModFileDateTime from the given unix
time.

    $member->setLastModFileDateTimeFromUnix( time() );

=item internalFileAttributes()

Return the internal file attributes field from the zip
header. This is only set for members read from a zip file.

=item externalFileAttributes()

Return member attributes as read from the ZIP file. Note that
these are NOT UNIX!

lib/Archive/Zip/DirectoryMember.pm  view on Meta::CPAN

    if (-e $fileName) {

        # -e does NOT do a full stat, so we need to do one now
        if (-d _ ) {
            my @stat = stat(_);
            $self->unixFileAttributes($stat[2]);
            my $mod_t = $stat[9];
            if ($^O eq 'MSWin32' and !$mod_t) {
                $mod_t = time();
            }
            $self->setLastModFileDateTimeFromUnix($mod_t);

        } else {    # hmm.. trying to add a non-directory?
            _error($fileName, ' exists but is not a directory');
            return undef;
        }
    } else {
        $self->unixFileAttributes($self->DEFAULT_DIRECTORY_PERMISSIONS);
        $self->setLastModFileDateTimeFromUnix(time());
    }
    return $self;
}

sub externalFileName {
    shift->{'externalFileName'};
}

sub isDirectory {
    return 1;

lib/Archive/Zip/Member.pm  view on Meta::CPAN

    # headers, regardless of whether the member has an zip64
    # extended information extra field or not:
    #
    #   version made by:
    #     30
    #
    #   version needed to extract:
    #     10 for directory and stored entries
    #     20 for anything else
    my $self  = {
        'lastModFileDateTime'      => 0,
        'fileAttributeFormat'      => FA_UNIX,
        'zip64'                    => 0,
        'desiredZip64Mode'         => ZIP64_AS_NEEDED,
        'versionMadeBy'            => 20,
        'versionNeededToExtract'   => 20,
        'bitFlag'                  => ($Archive::Zip::UNICODE ? 0x0800 : 0),
        'compressionMethod'        => COMPRESSION_STORED,
        'desiredCompressionMethod' => COMPRESSION_STORED,
        'desiredCompressionLevel'  => COMPRESSION_LEVEL_NONE,
        'internalFileAttributes'   => 0,

lib/Archive/Zip/Member.pm  view on Meta::CPAN


sub fileNameAsBytes {
    my $self  = shift;
    my $bytes = $self->{'fileName'};
    if($self->{'bitFlag'} & 0x800){
        $bytes = Encode::encode_utf8($bytes);
    }
    return $bytes;
}

sub lastModFileDateTime {
    my $modTime = shift->{'lastModFileDateTime'};
    $modTime =~ m/^(\d+)$/;           # untaint
    return $1;
}

sub lastModTime {
    my $self = shift;
    return _dosToUnixTime($self->lastModFileDateTime());
}

sub setLastModFileDateTimeFromUnix {
    my $self   = shift;
    my $time_t = shift;
    $self->{'lastModFileDateTime'} = _unixToDosTime($time_t);
}

sub internalFileAttributes {
    shift->{'internalFileAttributes'};
}

sub externalFileAttributes {
    shift->{'externalFileAttributes'};
}

lib/Archive/Zip/Member.pm  view on Meta::CPAN


    my $signatureData = pack(SIGNATURE_FORMAT, LOCAL_FILE_HEADER_SIGNATURE);
    $self->_print($fh, $signatureData)
      or return _ioError("writing local header signature");

    my $header =
      pack(LOCAL_FILE_HEADER_FORMAT,
           $versionNeededToExtract,
           $self->{'bitFlag'},
           $self->desiredCompressionMethod(),
           $self->lastModFileDateTime(),
           $crc32,
           $compressedSize,
           $uncompressedSize,
           $fileNameLength,
           $localFieldLength);
    $self->_print($fh, $header)
      or return _ioError("writing local header");

    # Write these only if required
    if (! $refresh || $zip64) {

lib/Archive/Zip/Member.pm  view on Meta::CPAN

    $self->_print($fh, $sigData)
      or return _ioError("writing central directory header signature");

    my $header = pack(
        CENTRAL_DIRECTORY_FILE_HEADER_FORMAT,
        $versionMadeBy,
        $self->fileAttributeFormat(),
        $versionNeededToExtract,
        $self->bitFlag(),
        $self->desiredCompressionMethod(),
        $self->lastModFileDateTime(),
        $self->crc32(),            # these three fields should have been updated
        $compressedSize,           # by writing the data stream out
        $uncompressedSize,         #
        $fileNameLength,
        $extraFieldLength,
        $fileCommentLength,
        0,                         # {'diskNumberStart'},
        $self->internalFileAttributes(),
        $self->externalFileAttributes(),
        $localHeaderRelativeOffset);

lib/Archive/Zip/Member.pm  view on Meta::CPAN


    @keys = (0x12345678, 0x23456789, 0x34567890);
    _update_keys($_) for unpack "C*", $pass;

    # DDumper { uk => [ @keys ] };

    my $head = substr $buff, 0, 12, "";
    my @head = map { _zdecode($_) } unpack "C*", $head;
    my $x =
      $self->{externalFileAttributes}
      ? ($self->{lastModFileDateTime} >> 8) & 0xff
      : $self->{crc32} >> 24;
    $head[-1] == $x or return "";    # Password fail

    # Worth checking ...
    $self->{crc32c} = (unpack LOCAL_FILE_HEADER_FORMAT, pack "C*", @head)[3];

    # DHexDump ($buff);
    $buff = pack "C*" => map { _zdecode($_) } unpack "C*" => $buff;

    # DHexDump ($buff);

lib/Archive/Zip/NewFileMember.pm  view on Meta::CPAN

    $self->{'externalFileName'}  = $fileName;
    $self->{'compressionMethod'} = COMPRESSION_STORED;
    my @stat = stat(_);
    $self->{'compressedSize'} = $self->{'uncompressedSize'} = $stat[7];
    $self->desiredCompressionMethod(
        ($self->compressedSize() > 0)
        ? COMPRESSION_DEFLATED
        : COMPRESSION_STORED
    );
    $self->unixFileAttributes($stat[2]);
    $self->setLastModFileDateTimeFromUnix($stat[9]);
    $self->isTextFile(-T _ );
    return $self;
}

sub rewindData {
    my $self = shift;

    my $status = $self->SUPER::rewindData(@_);
    return $status unless $status == AZ_OK;

lib/Archive/Zip/StringMember.pm  view on Meta::CPAN

# Can take a ref to a string as well.
sub _newFromString {
    my $class  = shift;
    my $string = shift;
    my $name   = shift;
    my $self   = $class->new(@_);
    $self->contents($string);
    $self->fileName($name) if defined($name);

    # Set the file date to now
    $self->setLastModFileDateTimeFromUnix(time());
    $self->unixFileAttributes($self->DEFAULT_FILE_PERMISSIONS);
    return $self;
}

sub _become {
    my $self     = shift;
    my $newClass = shift;
    return $self if ref($self) eq $newClass;
    delete($self->{'contents'});
    return $self->SUPER::_become($newClass);

lib/Archive/Zip/ZipFileMember.pm  view on Meta::CPAN

    if ($bytesRead != LOCAL_FILE_HEADER_LENGTH) {
        return _ioError("reading local file header");
    }
    my $fileNameLength;
    my $extraFieldLength;
    my $bitFlag;
    (
        undef,    # $self->{'versionNeededToExtract'},
        $bitFlag,
        undef,    # $self->{'compressionMethod'},
        undef,    # $self->{'lastModFileDateTime'},
        undef,    # $crc32,
        undef,    # $compressedSize,
        undef,    # $uncompressedSize,
        $fileNameLength,
        $extraFieldLength
    ) = unpack(LOCAL_FILE_HEADER_FORMAT, $header);

    if ($fileNameLength) {
        $self->fh()->seek($fileNameLength, IO::Seekable::SEEK_CUR)
          or return _ioError("skipping local file name");

lib/Archive/Zip/ZipFileMember.pm  view on Meta::CPAN

    if ($bytesRead != LOCAL_FILE_HEADER_LENGTH) {
        return _ioError("reading local file header");
    }
    my $fileNameLength;
    my $crc32;
    my $compressedSize;
    my $uncompressedSize;
    my $extraFieldLength;
    (
        $self->{'versionNeededToExtract'}, $self->{'bitFlag'},
        $self->{'compressionMethod'},      $self->{'lastModFileDateTime'},
        $crc32,                            $compressedSize,
        $uncompressedSize,                 $fileNameLength,
        $extraFieldLength
    ) = unpack(LOCAL_FILE_HEADER_FORMAT, $header);

    if ($fileNameLength) {
        my $fileName;
        $bytesRead = $self->fh()->read($fileName, $fileNameLength);
        if ($bytesRead != $fileNameLength) {
            return _ioError("reading local file name");

lib/Archive/Zip/ZipFileMember.pm  view on Meta::CPAN

    if ($bytesRead != CENTRAL_DIRECTORY_FILE_HEADER_LENGTH) {
        return _ioError("reading central dir header");
    }
    my ($fileNameLength, $extraFieldLength, $fileCommentLength);
    (
        $self->{'versionMadeBy'},
        $self->{'fileAttributeFormat'},
        $self->{'versionNeededToExtract'},
        $self->{'bitFlag'},
        $self->{'compressionMethod'},
        $self->{'lastModFileDateTime'},
        $self->{'crc32'},
        $self->{'compressedSize'},
        $self->{'uncompressedSize'},
        $fileNameLength,
        $extraFieldLength,
        $fileCommentLength,
        $self->{'diskNumberStart'},
        $self->{'internalFileAttributes'},
        $self->{'externalFileAttributes'},
        $self->{'localHeaderRelativeOffset'}

t/02_main.t  view on Meta::CPAN

#--------- check time conversion

foreach my $unix_time (
    315576062,  315576064,  315580000,  315600000,
    316000000,  320000000,  400000000,  500000000,
    600000000,  700000000,  800000000,  900000000,
    1000000000, 1100000000, 1200000000, int(time() / 2) * 2,
  ) {
    my $dos_time   = Archive::Zip::Member::_unixToDosTime($unix_time);
    my $round_trip = Archive::Zip::Member::_dosToUnixTime($dos_time);
    is($unix_time, $round_trip, 'Got expected DOS DateTime value');
}

#####################################################################
# Testing Archives

# Enjoy the non-indented freedom!
for my $desiredZip64Mode (ZIP64_AS_NEEDED, ZIP64_EOCD, ZIP64_HEADERS) {

next unless ZIP64_SUPPORTED || $desiredZip64Mode == ZIP64_AS_NEEDED;

t/02_main.t  view on Meta::CPAN

my $dirName    = testPath();

# addDirectory	# Archive::Zip::Archive
# new	# Archive::Zip::Member
my $member = $zip->addDirectory($memberName);
ok(defined($member));
is($member->fileName(), $memberName);

# On some (Windows systems) the modification time is
# corrupted. Save this to check later.
my $dirTime = $member->lastModFileDateTime();

# members	# Archive::Zip::Archive
@members = $zip->members();
is(scalar(@members), 1);
is($members[0],      $member);

# numberOfMembers	# Archive::Zip::Archive
$numberOfMembers = $zip->numberOfMembers();
is($numberOfMembers, 1);

# writeToFileNamed	# Archive::Zip::Archive
azok($zip->writeToFileNamed(OUTPUTZIP));

# Does the modification time get corrupted?
is(($zip->members)[0]->lastModFileDateTime(), $dirTime);

azuztok();

#--------- extract the directory by name
rmdir($dirName) or die;
azok($zip->extractMember($memberName));
ok(-d $dirName);

#--------- extract the directory by identity
rmdir($dirName) or die;

t/18_bug_92205.t  view on Meta::CPAN

for my $test (@TESTS)
{
    my ($infile, $reffile, $method) = @$test;
    $infile = dataPath($infile);
    $reffile = dataPath($reffile);
    my $outfile = OUTPUTZIP;

    passThrough($infile, $outfile, sub {
        my $member = shift;
        $member->desiredCompressionMethod($method) if defined($method);
        $member->setLastModFileDateTimeFromUnix($member->lastModTime());
    });
    azuztok($outfile, 'name' => "\"unzip -t\" ok after $infile to $outfile");

    my $outtext = readFile($outfile);
    my $reftext = readFile($reffile);
    ok($outtext eq $reftext, "$outfile eq $reffile");
}



( run in 0.466 second using v1.01-cache-2.11-cpan-05444aca049 )