diff options
author | Chris 'BinGOs' Williams <chris@bingosnet.co.uk> | 2011-06-21 21:41:34 +0100 |
---|---|---|
committer | Chris 'BinGOs' Williams <chris@bingosnet.co.uk> | 2011-06-21 22:22:18 +0100 |
commit | 529174d6b8367f9bfd259c344b7428a658857cc2 (patch) | |
tree | 9898da8edd55fa5178aeb215cf3770397c1a0285 /cpan/IO-Compress/lib/IO | |
parent | bc771c2e09e99a405d943901ac6d2c7fa1c98e23 (diff) | |
download | perl-529174d6b8367f9bfd259c344b7428a658857cc2.tar.gz |
Update IO-Compress to CPAN version 2.036
[DELTA]
2.036 18 June 2011
* IO::Compress::Zip & IO::Uncompress::Unzip
- Added support for LZMA (method 14) compression/uncompresion.
* IO::Compress::Unzip
- Fixed CRC issue when compression is Store or Bzip2 and Strict option
is set.
* IO::Compress::Zip
- Fixed Zip64 issue where the content size is exactly 0xFFFFFFFF
Diffstat (limited to 'cpan/IO-Compress/lib/IO')
25 files changed, 650 insertions, 182 deletions
diff --git a/cpan/IO-Compress/lib/IO/Compress/Adapter/Bzip2.pm b/cpan/IO-Compress/lib/IO/Compress/Adapter/Bzip2.pm index 72de92cd1e..d72008c9fd 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Adapter/Bzip2.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Adapter/Bzip2.pm @@ -4,13 +4,13 @@ use strict; use warnings; use bytes; -use IO::Compress::Base::Common 2.035 qw(:Status); +use IO::Compress::Base::Common 2.036 qw(:Status); #use Compress::Bzip2 ; -use Compress::Raw::Bzip2 2.035 ; +use Compress::Raw::Bzip2 2.036 ; our ($VERSION); -$VERSION = '2.035'; +$VERSION = '2.036'; sub mkCompObject { diff --git a/cpan/IO-Compress/lib/IO/Compress/Adapter/Deflate.pm b/cpan/IO-Compress/lib/IO/Compress/Adapter/Deflate.pm index 568740655e..ae060ee8d6 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Adapter/Deflate.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Adapter/Deflate.pm @@ -4,12 +4,12 @@ use strict; use warnings; use bytes; -use IO::Compress::Base::Common 2.035 qw(:Status); +use IO::Compress::Base::Common 2.036 qw(:Status); -use Compress::Raw::Zlib 2.035 qw(Z_OK Z_FINISH MAX_WBITS) ; +use Compress::Raw::Zlib 2.036 qw(Z_OK Z_FINISH MAX_WBITS) ; our ($VERSION); -$VERSION = '2.035'; +$VERSION = '2.036'; sub mkCompObject { diff --git a/cpan/IO-Compress/lib/IO/Compress/Adapter/Identity.pm b/cpan/IO-Compress/lib/IO/Compress/Adapter/Identity.pm index 59333d7227..c0b4eeffb3 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Adapter/Identity.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Adapter/Identity.pm @@ -4,10 +4,10 @@ use strict; use warnings; use bytes; -use IO::Compress::Base::Common 2.035 qw(:Status); +use IO::Compress::Base::Common 2.036 qw(:Status); our ($VERSION); -$VERSION = '2.035'; +$VERSION = '2.036'; sub mkCompObject { diff --git a/cpan/IO-Compress/lib/IO/Compress/Base.pm b/cpan/IO-Compress/lib/IO/Compress/Base.pm index 3bf46bd157..cbfaa007fc 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Base.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Base.pm @@ -6,7 +6,7 @@ require 5.004 ; use strict ; use warnings; -use IO::Compress::Base::Common 2.035 ; +use IO::Compress::Base::Common 2.036 ; use IO::File qw(SEEK_SET SEEK_END); ; use Scalar::Util qw(blessed readonly); @@ -20,7 +20,7 @@ use bytes; our (@ISA, $VERSION); @ISA = qw(Exporter IO::File); -$VERSION = '2.035'; +$VERSION = '2.036'; #Can't locate object method "SWASHNEW" via package "utf8" (perhaps you forgot to load "utf8"?) at .../ext/Compress-Zlib/Gzip/blib/lib/Compress/Zlib/Common.pm line 16. @@ -106,6 +106,14 @@ sub writeAt return 1; } +sub outputPayload +{ + + my $self = shift ; + return $self->output(@_); +} + + sub output { my $self = shift ; @@ -275,6 +283,7 @@ sub _create *$obj->{Header} = $obj->mkHeader($got) ; $obj->output( *$obj->{Header} ) or return undef; + $obj->beforePayload(); } else { @@ -625,7 +634,7 @@ sub syswrite *$self->{CompSize}->add(length $outBuffer) ; - $self->output($outBuffer) + $self->outputPayload($outBuffer) or return undef; return $buffer_length; @@ -679,7 +688,7 @@ sub flush *$self->{CompSize}->add(length $outBuffer) ; - $self->output($outBuffer) + $self->outputPayload($outBuffer) or return 0; if ( defined *$self->{FH} ) { @@ -690,6 +699,10 @@ sub flush return 1; } +sub beforePayload +{ +} + sub newStream { my $self = shift ; @@ -713,6 +726,8 @@ sub newStream *$self->{UnCompSize}->reset(); *$self->{CompSize}->reset(); + $self->beforePayload(); + return 1 ; } diff --git a/cpan/IO-Compress/lib/IO/Compress/Base/Common.pm b/cpan/IO-Compress/lib/IO/Compress/Base/Common.pm index 61db06da8f..01c608b800 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Base/Common.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Base/Common.pm @@ -11,7 +11,7 @@ use File::GlobMapper; require Exporter; our ($VERSION, @ISA, @EXPORT, %EXPORT_TAGS, $HAS_ENCODE); @ISA = qw(Exporter); -$VERSION = '2.035'; +$VERSION = '2.036'; @EXPORT = qw( isaFilehandle isaFilename whatIsInput whatIsOutput isaFileGlobString cleanFileGlobString oneTarget @@ -901,9 +901,13 @@ sub add $self->[HIGH] += $value->[HIGH] ; $value = $value->[LOW]; } + elsif ($value > MAX32) { + $self->[HIGH] += int($value / HI_1) ; + $value = $value % HI_1; + } my $available = MAX32 - $self->[LOW] ; - + if ($value > $available) { ++ $self->[HIGH] ; $self->[LOW] = $value - $available - 1; @@ -911,7 +915,33 @@ sub add else { $self->[LOW] += $value ; } +} + +sub subtract +{ + my $self = shift; + my $value = shift; + + if (ref $value eq 'U64') { + + if ($value->[HIGH]) { + die "bad" + if $self->[HIGH] == 0 || + $value->[HIGH] > $self->[HIGH] ; + + $self->[HIGH] -= $value->[HIGH] ; + } + + $value = $value->[LOW] ; + } + if ($value > $self->[LOW]) { + -- $self->[HIGH] ; + $self->[LOW] = MAX32 - $self->[LOW] ; + } + else { + $self->[LOW] -= $value; + } } sub equal @@ -929,6 +959,12 @@ sub is64bit return $self->[HIGH] > 0 ; } +sub isAlmost64bit +{ + my $self = shift; + return $self->[HIGH] > 0 || $self->[LOW] == MAX32 ; +} + sub getPacked_V64 { my $self = shift; @@ -951,6 +987,21 @@ sub pack_V64 } +sub full32 +{ + return $_[0] == MAX32 ; +} + +sub Value_VV64 +{ + my $buffer = shift; + + my ($lo, $hi) = unpack ("V V" , $buffer); + no warnings 'uninitialized'; + return $hi * HI_1 + $lo; +} + + package IO::Compress::Base::Common; 1; diff --git a/cpan/IO-Compress/lib/IO/Compress/Bzip2.pm b/cpan/IO-Compress/lib/IO/Compress/Bzip2.pm index 67ba59f07c..19138eac3e 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Bzip2.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Bzip2.pm @@ -5,16 +5,16 @@ use warnings; use bytes; require Exporter ; -use IO::Compress::Base 2.035 ; +use IO::Compress::Base 2.036 ; -use IO::Compress::Base::Common 2.035 qw(createSelfTiedObject); -use IO::Compress::Adapter::Bzip2 2.035 ; +use IO::Compress::Base::Common 2.036 qw(createSelfTiedObject); +use IO::Compress::Adapter::Bzip2 2.036 ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $Bzip2Error); -$VERSION = '2.035'; +$VERSION = '2.036'; $Bzip2Error = ''; @ISA = qw(Exporter IO::Compress::Base); @@ -51,7 +51,7 @@ sub getExtraParams { my $self = shift ; - use IO::Compress::Base::Common 2.035 qw(:Parse); + use IO::Compress::Base::Common 2.036 qw(:Parse); return ( 'BlockSize100K' => [0, 1, Parse_unsigned, 1], diff --git a/cpan/IO-Compress/lib/IO/Compress/Deflate.pm b/cpan/IO-Compress/lib/IO/Compress/Deflate.pm index d5a2ad0b0f..0041395a4f 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Deflate.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Deflate.pm @@ -6,16 +6,16 @@ use bytes; require Exporter ; -use IO::Compress::RawDeflate 2.035 ; +use IO::Compress::RawDeflate 2.036 ; -use Compress::Raw::Zlib 2.035 ; -use IO::Compress::Zlib::Constants 2.035 ; -use IO::Compress::Base::Common 2.035 qw(createSelfTiedObject); +use Compress::Raw::Zlib 2.036 ; +use IO::Compress::Zlib::Constants 2.036 ; +use IO::Compress::Base::Common 2.036 qw(createSelfTiedObject); our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $DeflateError); -$VERSION = '2.035'; +$VERSION = '2.036'; $DeflateError = ''; @ISA = qw(Exporter IO::Compress::RawDeflate); diff --git a/cpan/IO-Compress/lib/IO/Compress/Gzip.pm b/cpan/IO-Compress/lib/IO/Compress/Gzip.pm index c45c0764bf..fd567a9b5a 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Gzip.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Gzip.pm @@ -8,12 +8,12 @@ use warnings; use bytes; -use IO::Compress::RawDeflate 2.035 ; +use IO::Compress::RawDeflate 2.036 ; -use Compress::Raw::Zlib 2.035 ; -use IO::Compress::Base::Common 2.035 qw(:Status :Parse createSelfTiedObject); -use IO::Compress::Gzip::Constants 2.035 ; -use IO::Compress::Zlib::Extra 2.035 ; +use Compress::Raw::Zlib 2.036 ; +use IO::Compress::Base::Common 2.036 qw(:Status :Parse createSelfTiedObject); +use IO::Compress::Gzip::Constants 2.036 ; +use IO::Compress::Zlib::Extra 2.036 ; BEGIN { @@ -27,7 +27,7 @@ require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $GzipError); -$VERSION = '2.035'; +$VERSION = '2.036'; $GzipError = '' ; @ISA = qw(Exporter IO::Compress::RawDeflate); diff --git a/cpan/IO-Compress/lib/IO/Compress/Gzip/Constants.pm b/cpan/IO-Compress/lib/IO/Compress/Gzip/Constants.pm index 3329f55915..c196da4b9f 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Gzip/Constants.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Gzip/Constants.pm @@ -9,7 +9,7 @@ require Exporter; our ($VERSION, @ISA, @EXPORT, %GZIP_OS_Names); our ($GZIP_FNAME_INVALID_CHAR_RE, $GZIP_FCOMMENT_INVALID_CHAR_RE); -$VERSION = '2.035'; +$VERSION = '2.036'; @ISA = qw(Exporter); diff --git a/cpan/IO-Compress/lib/IO/Compress/RawDeflate.pm b/cpan/IO-Compress/lib/IO/Compress/RawDeflate.pm index 0dda715338..3bdce05af3 100644 --- a/cpan/IO-Compress/lib/IO/Compress/RawDeflate.pm +++ b/cpan/IO-Compress/lib/IO/Compress/RawDeflate.pm @@ -7,16 +7,16 @@ use warnings; use bytes; -use IO::Compress::Base 2.035 ; -use IO::Compress::Base::Common 2.035 qw(:Status createSelfTiedObject); -use IO::Compress::Adapter::Deflate 2.035 ; +use IO::Compress::Base 2.036 ; +use IO::Compress::Base::Common 2.036 qw(:Status createSelfTiedObject); +use IO::Compress::Adapter::Deflate 2.036 ; require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %DEFLATE_CONSTANTS, %EXPORT_TAGS, $RawDeflateError); -$VERSION = '2.035'; +$VERSION = '2.036'; $RawDeflateError = ''; @ISA = qw(Exporter IO::Compress::Base); @@ -142,8 +142,8 @@ sub getZlibParams { my $self = shift ; - use IO::Compress::Base::Common 2.035 qw(:Parse); - use Compress::Raw::Zlib 2.035 qw(Z_DEFLATED Z_DEFAULT_COMPRESSION Z_DEFAULT_STRATEGY); + use IO::Compress::Base::Common 2.036 qw(:Parse); + use Compress::Raw::Zlib 2.036 qw(Z_DEFLATED Z_DEFAULT_COMPRESSION Z_DEFAULT_STRATEGY); return ( diff --git a/cpan/IO-Compress/lib/IO/Compress/Zip.pm b/cpan/IO-Compress/lib/IO/Compress/Zip.pm index f6fcf450f2..8e8d69327f 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Zip.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Zip.pm @@ -4,27 +4,27 @@ use strict ; use warnings; use bytes; -use IO::Compress::Base::Common 2.035 qw(:Status createSelfTiedObject); -use IO::Compress::RawDeflate 2.035 ; -use IO::Compress::Adapter::Deflate 2.035 ; -use IO::Compress::Adapter::Identity 2.035 ; -use IO::Compress::Zlib::Extra 2.035 ; -use IO::Compress::Zip::Constants 2.035 ; +use IO::Compress::Base::Common 2.036 qw(:Status createSelfTiedObject); +use IO::Compress::RawDeflate 2.036 ; +use IO::Compress::Adapter::Deflate 2.036 ; +use IO::Compress::Adapter::Identity 2.036 ; +use IO::Compress::Zlib::Extra 2.036 ; +use IO::Compress::Zip::Constants 2.036 ; -use Compress::Raw::Zlib 2.035 qw(crc32) ; +use Compress::Raw::Zlib 2.036 qw(crc32) ; BEGIN { eval { require IO::Compress::Adapter::Bzip2 ; - import IO::Compress::Adapter::Bzip2 2.035 ; + import IO::Compress::Adapter::Bzip2 2.036 ; require IO::Compress::Bzip2 ; - import IO::Compress::Bzip2 2.035 ; + import IO::Compress::Bzip2 2.036 ; + } ; + eval { require IO::Compress::Adapter::Lzma ; + import IO::Compress::Adapter::Lzma 2.036 ; + require IO::Compress::Lzma ; + import IO::Compress::Lzma 2.036 ; } ; -# eval { require IO::Compress::Adapter::Lzma ; -# import IO::Compress::Adapter::Lzma 2.020 ; -# require IO::Compress::Lzma ; -# import IO::Compress::Lzma 2.035 ; -# } ; } @@ -32,7 +32,7 @@ require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $ZipError); -$VERSION = '2.035'; +$VERSION = '2.036'; $ZipError = ''; @ISA = qw(Exporter IO::Compress::RawDeflate); @@ -51,6 +51,7 @@ sub new my $obj = createSelfTiedObject($class, \$ZipError); $obj->_create(undef, @_); + } sub zip @@ -59,6 +60,27 @@ sub zip return $obj->_def(@_); } +sub beforePayload +{ + my $self = shift ; + + if (*$self->{ZipData}{Sparse} ) { + my $inc = 1024 * 100 ; + my $NULLS = ("\x00" x $inc) ; + my $sparse = *$self->{ZipData}{Sparse} ; + *$self->{CompSize}->add( $sparse ); + *$self->{UnCompSize}->add( $sparse ); + + *$self->{FH}->seek($sparse, IO::Handle::SEEK_CUR); + + *$self->{ZipData}{CRC32} = crc32($NULLS, *$self->{ZipData}{CRC32}) + for 1 .. int $sparse / $inc; + *$self->{ZipData}{CRC32} = crc32(substr($NULLS, 0, $sparse % $inc), + *$self->{ZipData}{CRC32}) + if $sparse % $inc; + } +} + sub mkComp { my $self = shift ; @@ -89,10 +111,12 @@ sub mkComp ); *$self->{ZipData}{CRC32} = crc32(undef); } -# elsif (*$self->{ZipData}{Method} == ZIP_CM_LZMA) { -# ($obj, $errstr, $errno) = IO::Compress::Adapter::Lzma::mkCompObject(); -# *$self->{ZipData}{CRC32} = crc32(undef); -# } + elsif (*$self->{ZipData}{Method} == ZIP_CM_LZMA) { + ($obj, $errstr, $errno) = IO::Compress::Adapter::Lzma::mkRawZipCompObject($got->value('Preset'), + $got->value('Extreme'), + ); + *$self->{ZipData}{CRC32} = crc32(undef); + } return $self->saveErrorString(undef, $errstr, $errno) if ! defined $obj; @@ -194,11 +218,14 @@ sub mkHeader if defined $param->value('ExtraFieldCentral'); } + my $method = *$self->{ZipData}{Method} ; my $gpFlag = 0 ; $gpFlag |= ZIP_GP_FLAG_STREAMING_MASK if *$self->{ZipData}{Stream} ; - my $method = *$self->{ZipData}{Method} ; + $gpFlag |= ZIP_GP_FLAG_LZMA_EOS_PRESENT + if $method == ZIP_CM_LZMA ; + my $version = $ZIP_CM_MIN_VERSIONS{$method}; $version = ZIP64_MIN_VERSION @@ -278,6 +305,7 @@ sub mkHeader *$self->{ZipData}{CentralHeader} = $ctl; + return $hdr; } @@ -307,6 +335,7 @@ sub mkTrailer my $data = $crc32 . $sizes ; + my $xtrasize = *$self->{UnCompSize}->getPacked_V64() ; # Uncompressed size $xtrasize .= *$self->{CompSize}->getPacked_V64() ; # Compressed size @@ -331,14 +360,14 @@ sub mkTrailer my $x = ''; # uncompressed length - if (*$self->{UnCompSize}->is64bit() ) { + if (*$self->{UnCompSize}->isAlmost64bit() || *$self->{ZipData}{Zip64} > 1) { $x .= *$self->{UnCompSize}->getPacked_V64() ; } else { substr($ctl, 24, 4) = *$self->{UnCompSize}->getPacked_V32() ; } # compressed length - if (*$self->{CompSize}->is64bit() ) { + if (*$self->{CompSize}->isAlmost64bit() || *$self->{ZipData}{Zip64} > 1) { $x .= *$self->{CompSize}->getPacked_V64() ; } else { substr($ctl, 20, 4) = *$self->{CompSize}->getPacked_V32() ; @@ -475,9 +504,8 @@ sub ckParams ! defined $IO::Compress::Adapter::Bzip2::VERSION; return $self->saveErrorString(undef, "Lzma not available") - if $method == ZIP_CM_LZMA ; - #and - #! defined $IO::Compress::Adapter::Lzma::VERSION; + if $method == ZIP_CM_LZMA + and ! defined $IO::Compress::Adapter::Lzma::VERSION; *$self->{ZipData}{Method} = $method; @@ -499,9 +527,22 @@ sub ckParams if defined $IO::Compress::Bzip2::VERSION and ! IO::Compress::Bzip2::ckParams($self, $got); + if ($got->parsed('Sparse') ) { + *$self->{ZipData}{Sparse} = $got->value('Sparse') ; + *$self->{ZipData}{Method} = ZIP_CM_STORE; + } + return 1 ; } +sub outputPayload +{ + my $self = shift ; + return 1 if *$self->{ZipData}{Sparse} ; + return $self->output(@_); +} + + #sub newHeader #{ # my $self = shift ; @@ -513,13 +554,14 @@ sub getExtraParams { my $self = shift ; - use IO::Compress::Base::Common 2.035 qw(:Parse); - use Compress::Raw::Zlib 2.035 qw(Z_DEFLATED Z_DEFAULT_COMPRESSION Z_DEFAULT_STRATEGY); + use IO::Compress::Base::Common 2.036 qw(:Parse); + use Compress::Raw::Zlib 2.036 qw(Z_DEFLATED Z_DEFAULT_COMPRESSION Z_DEFAULT_STRATEGY); my @Bzip2 = (); @Bzip2 = IO::Compress::Bzip2::getExtraParams($self) if defined $IO::Compress::Bzip2::VERSION; + return ( # zlib behaviour @@ -531,7 +573,7 @@ sub getExtraParams # # Zip header fields 'Minimal' => [0, 1, Parse_boolean, 0], - 'Zip64' => [0, 1, Parse_boolean, 0], + 'Zip64' => [0, 1, Parse_any, 0], 'Comment' => [0, 1, Parse_any, ''], 'ZipComment'=> [0, 1, Parse_any, ''], 'Name' => [0, 1, Parse_any, ''], @@ -548,6 +590,13 @@ sub getExtraParams 'ExtraFieldLocal' => [0, 1, Parse_any, undef], 'ExtraFieldCentral'=> [0, 1, Parse_any, undef], + # Lzma + 'Preset' => [0, 1, Parse_unsigned, 6], + 'Extreme' => [1, 1, Parse_boolean, 0], + + # For internal use only + 'Sparse' => [0, 1, Parse_unsigned, 0], + @Bzip2, ); } @@ -705,11 +754,14 @@ zip files and buffers. It is not a general-purpose file archiver. If that is what you want, check out C<Archive::Zip>. At present three compression methods are supported by IO::Compress::Zip, -namely Store (no compression at all), Deflate and Bzip2. +namely Store (no compression at all), Deflate, Bzip2 and LZMA. Note that to create Bzip2 content, the module C<IO::Compress::Bzip2> must be installed. +Note that to create LZMA content, the module C<IO::Compress::Lzma> must +be installed. + For reading zip files/buffers, see the companion module L<IO::Uncompress::Unzip|IO::Uncompress::Unzip>. @@ -1139,12 +1191,12 @@ By default, no comment field is written to the zip file. =item C<< Method => $method >> -Controls which compression method is used. At present three compression -methods are supported, namely Store (no compression at all), Deflate and -Bzip2. +Controls which compression method is used. At present four compression +methods are supported, namely Store (no compression at all), Deflate, +Bzip2 and Lzma. -The symbols, ZIP_CM_STORE, ZIP_CM_DEFLATE and ZIP_CM_BZIP2 are used to -select the compression method. +The symbols, ZIP_CM_STORE, ZIP_CM_DEFLATE, ZIP_CM_BZIP2 and ZIP_CM_LZMA +are used to select the compression method. These constants are not imported by C<IO::Compress::Zip> by default. @@ -1156,6 +1208,10 @@ Note that to create Bzip2 content, the module C<IO::Compress::Bzip2> must be installed. A fatal error will be thrown if you attempt to create Bzip2 content when C<IO::Compress::Bzip2> is not available. +Note that to create Lzma content, the module C<IO::Compress::Lzma> must +be installed. A fatal error will be thrown if you attempt to create Lzma +content when C<IO::Compress::Lzma> is not available. + The default method is ZIP_CM_DEFLATE. =item C<< Stream => 0|1 >> @@ -1266,6 +1322,32 @@ otherwise. The default is 0. +=item C<< Preset => number >> + +Used to choose the LZMA compression preset. + +Valid values are 0-9 and C<LZMA_PRESET_DEFAULT>. + +0 is the fastest compression with the lowest memory usage and the lowest +compression. + +9 is the slowest compession with the highest memory usage but with the best +compression. + +This option is only valid if the C<Method> is ZIP_CM_LZMA. It is ignored +otherwise. + +Defaults to C<LZMA_PRESET_DEFAULT> (6). + +=item C<< Extreme => 0|1 >> + +Makes LZMA compression a lot slower, but a small compression gain. + +This option is only valid if the C<Method> is ZIP_CM_LZMA. It is ignored +otherwise. + +Defaults to 0. + =item -Level Defines the compression level used by zlib. The value should either be diff --git a/cpan/IO-Compress/lib/IO/Compress/Zip/Constants.pm b/cpan/IO-Compress/lib/IO/Compress/Zip/Constants.pm index e4600f545d..bebd5c4123 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Zip/Constants.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Zip/Constants.pm @@ -7,7 +7,7 @@ require Exporter; our ($VERSION, @ISA, @EXPORT, %ZIP_CM_MIN_VERSIONS); -$VERSION = '2.035'; +$VERSION = '2.036'; @ISA = qw(Exporter); @@ -39,6 +39,8 @@ $VERSION = '2.035'; ZIP_EXTRA_ID_EXT_TIMESTAMP ZIP_EXTRA_ID_INFO_ZIP_UNIX2 ZIP_EXTRA_ID_INFO_ZIP_UNIXn + ZIP_EXTRA_ID_INFO_ZIP_Upath + ZIP_EXTRA_ID_INFO_ZIP_Ucom ZIP_EXTRA_ID_JAVA_EXE ZIP_OS_CODE_UNIX @@ -87,6 +89,8 @@ use constant ZIP_EXTRA_ID_ZIP64 => pack "v", 1; use constant ZIP_EXTRA_ID_EXT_TIMESTAMP => "UT"; use constant ZIP_EXTRA_ID_INFO_ZIP_UNIX2 => "Ux"; use constant ZIP_EXTRA_ID_INFO_ZIP_UNIXn => "ux"; +use constant ZIP_EXTRA_ID_INFO_ZIP_Upath => "up"; +use constant ZIP_EXTRA_ID_INFO_ZIP_Ucom => "uc"; use constant ZIP_EXTRA_ID_JAVA_EXE => pack "v", 0xCAFE; use constant ZIP64_MIN_VERSION => 45; diff --git a/cpan/IO-Compress/lib/IO/Compress/Zlib/Constants.pm b/cpan/IO-Compress/lib/IO/Compress/Zlib/Constants.pm index a96992b92a..eba9ce76bb 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Zlib/Constants.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Zlib/Constants.pm @@ -9,7 +9,7 @@ require Exporter; our ($VERSION, @ISA, @EXPORT); -$VERSION = '2.035'; +$VERSION = '2.036'; @ISA = qw(Exporter); diff --git a/cpan/IO-Compress/lib/IO/Compress/Zlib/Extra.pm b/cpan/IO-Compress/lib/IO/Compress/Zlib/Extra.pm index dda5d88c8f..692cc51009 100644 --- a/cpan/IO-Compress/lib/IO/Compress/Zlib/Extra.pm +++ b/cpan/IO-Compress/lib/IO/Compress/Zlib/Extra.pm @@ -8,9 +8,9 @@ use bytes; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS); -$VERSION = '2.035'; +$VERSION = '2.036'; -use IO::Compress::Gzip::Constants 2.035 ; +use IO::Compress::Gzip::Constants 2.036 ; sub ExtraFieldError { @@ -98,6 +98,38 @@ sub parseRawExtra return undef ; } +sub findID +{ + my $id_want = shift ; + my $data = shift; + + my $XLEN = length $data ; + + my $offset = 0 ; + while ($offset < $XLEN) { + + return undef + if $offset + GZIP_FEXTRA_SUBFIELD_HEADER_SIZE > $XLEN ; + + my $id = substr($data, $offset, GZIP_FEXTRA_SUBFIELD_ID_SIZE); + $offset += GZIP_FEXTRA_SUBFIELD_ID_SIZE; + + my $subLen = unpack("v", substr($data, $offset, + GZIP_FEXTRA_SUBFIELD_LEN_SIZE)); + $offset += GZIP_FEXTRA_SUBFIELD_LEN_SIZE ; + + return undef + if $offset + $subLen > $XLEN ; + + return substr($data, $offset, $subLen) + if $id eq $id_want ; + + $offset += $subLen ; + } + + return undef ; +} + sub mkSubField { diff --git a/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Bunzip2.pm b/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Bunzip2.pm index 4ed3a67895..dcc348209b 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Bunzip2.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Bunzip2.pm @@ -4,12 +4,12 @@ use strict; use warnings; use bytes; -use IO::Compress::Base::Common 2.035 qw(:Status); +use IO::Compress::Base::Common 2.036 qw(:Status); -use Compress::Raw::Bzip2 2.035 ; +use Compress::Raw::Bzip2 2.036 ; our ($VERSION, @ISA); -$VERSION = '2.035'; +$VERSION = '2.036'; sub mkUncompObject { diff --git a/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Identity.pm b/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Identity.pm index 879a7f61af..0ac4b212bb 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Identity.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Identity.pm @@ -4,13 +4,13 @@ use warnings; use strict; use bytes; -use IO::Compress::Base::Common 2.035 qw(:Status); +use IO::Compress::Base::Common 2.036 qw(:Status); our ($VERSION); -$VERSION = '2.035'; +$VERSION = '2.036'; -use Compress::Raw::Zlib 2.035 (); +use Compress::Raw::Zlib 2.036 (); sub mkUncompObject { diff --git a/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Inflate.pm b/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Inflate.pm index 25d70e142d..b5cb07bafc 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Inflate.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/Adapter/Inflate.pm @@ -4,11 +4,11 @@ use strict; use warnings; use bytes; -use IO::Compress::Base::Common 2.035 qw(:Status); -use Compress::Raw::Zlib 2.035 qw(Z_OK Z_BUF_ERROR Z_STREAM_END Z_FINISH MAX_WBITS); +use IO::Compress::Base::Common 2.036 qw(:Status); +use Compress::Raw::Zlib 2.036 qw(Z_OK Z_BUF_ERROR Z_STREAM_END Z_FINISH MAX_WBITS); our ($VERSION); -$VERSION = '2.035'; +$VERSION = '2.036'; diff --git a/cpan/IO-Compress/lib/IO/Uncompress/AnyInflate.pm b/cpan/IO-Compress/lib/IO/Uncompress/AnyInflate.pm index 3b6dc38fc3..6efbd788ef 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/AnyInflate.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/AnyInflate.pm @@ -6,22 +6,22 @@ use strict; use warnings; use bytes; -use IO::Compress::Base::Common 2.035 qw(createSelfTiedObject); +use IO::Compress::Base::Common 2.036 qw(createSelfTiedObject); -use IO::Uncompress::Adapter::Inflate 2.035 (); +use IO::Uncompress::Adapter::Inflate 2.036 (); -use IO::Uncompress::Base 2.035 ; -use IO::Uncompress::Gunzip 2.035 ; -use IO::Uncompress::Inflate 2.035 ; -use IO::Uncompress::RawInflate 2.035 ; -use IO::Uncompress::Unzip 2.035 ; +use IO::Uncompress::Base 2.036 ; +use IO::Uncompress::Gunzip 2.036 ; +use IO::Uncompress::Inflate 2.036 ; +use IO::Uncompress::RawInflate 2.036 ; +use IO::Uncompress::Unzip 2.036 ; require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $AnyInflateError); -$VERSION = '2.035'; +$VERSION = '2.036'; $AnyInflateError = ''; @ISA = qw( Exporter IO::Uncompress::Base ); @@ -48,7 +48,7 @@ sub anyinflate sub getExtraParams { - use IO::Compress::Base::Common 2.035 qw(:Parse); + use IO::Compress::Base::Common 2.036 qw(:Parse); return ( 'RawInflate' => [1, 1, Parse_boolean, 0] ) ; } diff --git a/cpan/IO-Compress/lib/IO/Uncompress/AnyUncompress.pm b/cpan/IO-Compress/lib/IO/Uncompress/AnyUncompress.pm index 08c122f2c4..97673fd852 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/AnyUncompress.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/AnyUncompress.pm @@ -4,16 +4,16 @@ use strict; use warnings; use bytes; -use IO::Compress::Base::Common 2.035 qw(createSelfTiedObject); +use IO::Compress::Base::Common 2.036 qw(createSelfTiedObject); -use IO::Uncompress::Base 2.035 ; +use IO::Uncompress::Base 2.036 ; require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $AnyUncompressError); -$VERSION = '2.035'; +$VERSION = '2.036'; $AnyUncompressError = ''; @ISA = qw( Exporter IO::Uncompress::Base ); @@ -27,22 +27,22 @@ Exporter::export_ok_tags('all'); BEGIN { - eval ' use IO::Uncompress::Adapter::Inflate 2.035 ;'; - eval ' use IO::Uncompress::Adapter::Bunzip2 2.035 ;'; - eval ' use IO::Uncompress::Adapter::LZO 2.035 ;'; - eval ' use IO::Uncompress::Adapter::Lzf 2.035 ;'; + eval ' use IO::Uncompress::Adapter::Inflate 2.036 ;'; + eval ' use IO::Uncompress::Adapter::Bunzip2 2.036 ;'; + eval ' use IO::Uncompress::Adapter::LZO 2.036 ;'; + eval ' use IO::Uncompress::Adapter::Lzf 2.036 ;'; eval ' use IO::Uncompress::Adapter::UnLzma 2.020 ;'; eval ' use IO::Uncompress::Adapter::UnXz 2.020 ;'; - eval ' use IO::Uncompress::Bunzip2 2.035 ;'; - eval ' use IO::Uncompress::UnLzop 2.035 ;'; - eval ' use IO::Uncompress::Gunzip 2.035 ;'; - eval ' use IO::Uncompress::Inflate 2.035 ;'; - eval ' use IO::Uncompress::RawInflate 2.035 ;'; - eval ' use IO::Uncompress::Unzip 2.035 ;'; - eval ' use IO::Uncompress::UnLzf 2.035 ;'; - eval ' use IO::Uncompress::UnLzma 2.035 ;'; - eval ' use IO::Uncompress::UnXz 2.035 ;'; + eval ' use IO::Uncompress::Bunzip2 2.036 ;'; + eval ' use IO::Uncompress::UnLzop 2.036 ;'; + eval ' use IO::Uncompress::Gunzip 2.036 ;'; + eval ' use IO::Uncompress::Inflate 2.036 ;'; + eval ' use IO::Uncompress::RawInflate 2.036 ;'; + eval ' use IO::Uncompress::Unzip 2.036 ;'; + eval ' use IO::Uncompress::UnLzf 2.036 ;'; + eval ' use IO::Uncompress::UnLzma 2.036 ;'; + eval ' use IO::Uncompress::UnXz 2.036 ;'; } sub new @@ -60,7 +60,7 @@ sub anyuncompress sub getExtraParams { - use IO::Compress::Base::Common 2.035 qw(:Parse); + use IO::Compress::Base::Common 2.036 qw(:Parse); return ( 'RawInflate' => [1, 1, Parse_boolean, 0] , 'UnLzma' => [1, 1, Parse_boolean, 0] ) ; } diff --git a/cpan/IO-Compress/lib/IO/Uncompress/Base.pm b/cpan/IO-Compress/lib/IO/Uncompress/Base.pm index f432b0e2c6..7deb7483a7 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/Base.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/Base.pm @@ -9,12 +9,12 @@ our (@ISA, $VERSION, @EXPORT_OK, %EXPORT_TAGS); @ISA = qw(Exporter IO::File); -$VERSION = '2.035'; +$VERSION = '2.036'; use constant G_EOF => 0 ; use constant G_ERR => -1 ; -use IO::Compress::Base::Common 2.035 ; +use IO::Compress::Base::Common 2.036 ; use IO::File ; use Symbol; @@ -140,18 +140,38 @@ sub smartSeek my $self = shift ; my $offset = shift ; my $truncate = shift; + my $position = shift || SEEK_SET; # TODO -- need to take prime into account if (defined *$self->{FH}) - { *$self->{FH}->seek($offset, SEEK_SET) } + { *$self->{FH}->seek($offset, $position) } else { - *$self->{BufferOffset} = $offset ; + if ($position == SEEK_END) { + *$self->{BufferOffset} = length ${ *$self->{Buffer} } + $offset ; + } + elsif ($position == SEEK_CUR) { + *$self->{BufferOffset} += $offset ; + } + else { + *$self->{BufferOffset} = $offset ; + } + substr(${ *$self->{Buffer} }, *$self->{BufferOffset}) = '' if $truncate; return 1; } } +sub smartTell +{ + my $self = shift ; + + if (defined *$self->{FH}) + { return *$self->{FH}->tell() } + else + { return *$self->{BufferOffset} } +} + sub smartWrite { my $self = shift ; @@ -882,7 +902,7 @@ sub _raw_read *$self->{TotalInflatedBytesRead} += $buf_len ; *$self->{UnCompSize}->add($buf_len) ; - $self->filterUncompressed($buffer); + $self->filterUncompressed($buffer, $before_len); if (*$self->{Encoding}) { $$buffer = *$self->{Encoding}->decode($$buffer); diff --git a/cpan/IO-Compress/lib/IO/Uncompress/Bunzip2.pm b/cpan/IO-Compress/lib/IO/Uncompress/Bunzip2.pm index 38a4fc8970..612abdc172 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/Bunzip2.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/Bunzip2.pm @@ -4,15 +4,15 @@ use strict ; use warnings; use bytes; -use IO::Compress::Base::Common 2.035 qw(:Status createSelfTiedObject); +use IO::Compress::Base::Common 2.036 qw(:Status createSelfTiedObject); -use IO::Uncompress::Base 2.035 ; -use IO::Uncompress::Adapter::Bunzip2 2.035 ; +use IO::Uncompress::Base 2.036 ; +use IO::Uncompress::Adapter::Bunzip2 2.036 ; require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $Bunzip2Error); -$VERSION = '2.035'; +$VERSION = '2.036'; $Bunzip2Error = ''; @ISA = qw( Exporter IO::Uncompress::Base ); @@ -40,7 +40,7 @@ sub getExtraParams { my $self = shift ; - use IO::Compress::Base::Common 2.035 qw(:Parse); + use IO::Compress::Base::Common 2.036 qw(:Parse); return ( 'Verbosity' => [1, 1, Parse_boolean, 0], diff --git a/cpan/IO-Compress/lib/IO/Uncompress/Gunzip.pm b/cpan/IO-Compress/lib/IO/Uncompress/Gunzip.pm index ecd3bc496e..61c961f87a 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/Gunzip.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/Gunzip.pm @@ -9,12 +9,12 @@ use strict ; use warnings; use bytes; -use IO::Uncompress::RawInflate 2.035 ; +use IO::Uncompress::RawInflate 2.036 ; -use Compress::Raw::Zlib 2.035 qw( crc32 ) ; -use IO::Compress::Base::Common 2.035 qw(:Status createSelfTiedObject); -use IO::Compress::Gzip::Constants 2.035 ; -use IO::Compress::Zlib::Extra 2.035 ; +use Compress::Raw::Zlib 2.036 qw( crc32 ) ; +use IO::Compress::Base::Common 2.036 qw(:Status createSelfTiedObject); +use IO::Compress::Gzip::Constants 2.036 ; +use IO::Compress::Zlib::Extra 2.036 ; require Exporter ; @@ -28,7 +28,7 @@ Exporter::export_ok_tags('all'); $GunzipError = ''; -$VERSION = '2.035'; +$VERSION = '2.036'; sub new { @@ -47,7 +47,7 @@ sub gunzip sub getExtraParams { - use IO::Compress::Base::Common 2.035 qw(:Parse); + use IO::Compress::Base::Common 2.036 qw(:Parse); return ( 'ParseExtra' => [1, 1, Parse_boolean, 0] ) ; } diff --git a/cpan/IO-Compress/lib/IO/Uncompress/Inflate.pm b/cpan/IO-Compress/lib/IO/Uncompress/Inflate.pm index ae920d3a1f..554bd3d21d 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/Inflate.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/Inflate.pm @@ -5,15 +5,15 @@ use strict ; use warnings; use bytes; -use IO::Compress::Base::Common 2.035 qw(:Status createSelfTiedObject); -use IO::Compress::Zlib::Constants 2.035 ; +use IO::Compress::Base::Common 2.036 qw(:Status createSelfTiedObject); +use IO::Compress::Zlib::Constants 2.036 ; -use IO::Uncompress::RawInflate 2.035 ; +use IO::Uncompress::RawInflate 2.036 ; require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $InflateError); -$VERSION = '2.035'; +$VERSION = '2.036'; $InflateError = ''; @ISA = qw( Exporter IO::Uncompress::RawInflate ); diff --git a/cpan/IO-Compress/lib/IO/Uncompress/RawInflate.pm b/cpan/IO-Compress/lib/IO/Uncompress/RawInflate.pm index de109fb0cd..7aacb2d962 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/RawInflate.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/RawInflate.pm @@ -5,16 +5,16 @@ use strict ; use warnings; use bytes; -use Compress::Raw::Zlib 2.035 ; -use IO::Compress::Base::Common 2.035 qw(:Status createSelfTiedObject); +use Compress::Raw::Zlib 2.036 ; +use IO::Compress::Base::Common 2.036 qw(:Status createSelfTiedObject); -use IO::Uncompress::Base 2.035 ; -use IO::Uncompress::Adapter::Inflate 2.035 ; +use IO::Uncompress::Base 2.036 ; +use IO::Uncompress::Adapter::Inflate 2.036 ; require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, %DEFLATE_CONSTANTS, $RawInflateError); -$VERSION = '2.035'; +$VERSION = '2.036'; $RawInflateError = ''; @ISA = qw( Exporter IO::Uncompress::Base ); diff --git a/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm b/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm index 5faeb3bf58..9edb795305 100644 --- a/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm +++ b/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm @@ -8,21 +8,22 @@ use strict ; use warnings; use bytes; -use IO::Uncompress::RawInflate 2.035 ; -use IO::Compress::Base::Common 2.035 qw(:Status createSelfTiedObject); -use IO::Uncompress::Adapter::Inflate 2.035 ; -use IO::Uncompress::Adapter::Identity 2.035 ; -use IO::Compress::Zlib::Extra 2.035 ; -use IO::Compress::Zip::Constants 2.035 ; +use IO::File; +use IO::Uncompress::RawInflate 2.036 ; +use IO::Compress::Base::Common 2.036 qw(:Status createSelfTiedObject); +use IO::Uncompress::Adapter::Inflate 2.036 ; +use IO::Uncompress::Adapter::Identity 2.036 ; +use IO::Compress::Zlib::Extra 2.036 ; +use IO::Compress::Zip::Constants 2.036 ; -use Compress::Raw::Zlib 2.035 qw(crc32) ; +use Compress::Raw::Zlib 2.036 qw(crc32) ; BEGIN { eval { require IO::Uncompress::Adapter::Bunzip2 ; import IO::Uncompress::Adapter::Bunzip2 } ; -# eval { require IO::Uncompress::Adapter::UnLzma ; -# import IO::Uncompress::Adapter::UnLzma } ; + eval { require IO::Uncompress::Adapter::UnLzma ; + import IO::Uncompress::Adapter::UnLzma } ; } @@ -30,7 +31,7 @@ require Exporter ; our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError, %headerLookup); -$VERSION = '2.035'; +$VERSION = '2.036'; $UnzipError = ''; @ISA = qw(Exporter IO::Uncompress::RawInflate); @@ -63,14 +64,15 @@ sub unzip sub getExtraParams { - use IO::Compress::Base::Common 2.035 qw(:Parse); + use IO::Compress::Base::Common 2.036 qw(:Parse); return ( # # Zip header fields 'Name' => [1, 1, Parse_any, undef], -# 'Stream' => [1, 1, Parse_boolean, 1], + 'Stream' => [1, 1, Parse_boolean, 0], + # This means reading the central directory to get # 1. the local header offsets # 2. The compressed data length @@ -415,7 +417,7 @@ sub skipCentralDirectory64Rec my $keep = $magic . $buffer ; my ($sizeLo, $sizeHi) = unpack ("V V", $buffer); - my $size = $sizeHi * 0xFFFFFFFF + $sizeLo; + my $size = $sizeHi * U64::MAX32 + $sizeLo; $self->fastForward($size) or return $self->TrailerError("Minimum header size is " . @@ -473,8 +475,8 @@ sub skipEndCentralDirectory #my $cntrlDirDiskNo = unpack ("v", substr($buffer, 6-4, 2)); #my $entriesInThisCD = unpack ("v", substr($buffer, 8-4, 2)); #my $entriesInCD = unpack ("v", substr($buffer, 10-4, 2)); - #my $sizeOfCD = unpack ("V", substr($buffer, 12-4, 2)); - #my $offsetToCD = unpack ("V", substr($buffer, 16-4, 2)); + #my $sizeOfCD = unpack ("V", substr($buffer, 12-4, 4)); + #my $offsetToCD = unpack ("V", substr($buffer, 16-4, 4)); my $comment_length = unpack ("v", substr($buffer, 20-4, 2)); @@ -601,14 +603,14 @@ sub _readZipHeader($) if (! $streamingMode) { my $offset = 0 ; - if ($uncompressedLength->get32bit() == 0xFFFFFFFF ) { + if (U64::full32 $uncompressedLength->get32bit() ) { $uncompressedLength = U64::newUnpack_V64 substr($buff, 0, 8); $offset += 8 ; } - if ($compressedLength->get32bit() == 0xFFFFFFFF) { + if (U64::full32 $compressedLength->get32bit() ) { $compressedLength = U64::newUnpack_V64 substr($buff, $offset, 8); @@ -650,34 +652,40 @@ sub _readZipHeader($) *$self->{Uncomp} = $obj; } -# elsif ($compressedMethod == ZIP_CM_LZMA) -# { -# return $self->HeaderError("Unsupported Compression format $compressedMethod") -# if ! defined $IO::Uncompress::Adapter::UnLzma::VERSION ; -# -# *$self->{Type} = 'zip-lzma'; -# my $LzmaHeader; -# $self->smartReadExact(\$LzmaHeader, 4) -# or return $self->saveErrorString(undef, "Truncated file"); -# my ($verHi, $verLo) = unpack ("CC", substr($LzmaHeader, 0, 2)); -# my $LzmaPropertiesSize = unpack ("v", substr($LzmaHeader, 2, 2)); -# -# -# my $LzmaPropertyData; -# $self->smartReadExact(\$LzmaPropertyData, $LzmaPropertiesSize) -# or return $self->saveErrorString(undef, "Truncated file"); -# #my $LzmaInfo = unpack ("C", substr($LzmaPropertyData, 0, 1)); -# #my $LzmaDictSize = unpack ("V", substr($LzmaPropertyData, 1, 4)); -# -# # Create an LZMA_Alone header -# $self->pushBack($LzmaPropertyData . -# $uncompressedLength->getPacked_V64()); -# -# my $obj = -# IO::Uncompress::Adapter::UnLzma::mkUncompObject(); -# -# *$self->{Uncomp} = $obj; -# } + elsif ($compressedMethod == ZIP_CM_LZMA) + { + return $self->HeaderError("Unsupported Compression format $compressedMethod") + if ! defined $IO::Uncompress::Adapter::UnLzma::VERSION ; + + *$self->{Type} = 'zip-lzma'; + my $LzmaHeader; + $self->smartReadExact(\$LzmaHeader, 4) + or return $self->saveErrorString(undef, "Truncated file"); + my ($verHi, $verLo) = unpack ("CC", substr($LzmaHeader, 0, 2)); + my $LzmaPropertiesSize = unpack ("v", substr($LzmaHeader, 2, 2)); + + + my $LzmaPropertyData; + $self->smartReadExact(\$LzmaPropertyData, $LzmaPropertiesSize) + or return $self->saveErrorString(undef, "Truncated file"); + #my $LzmaInfo = unpack ("C", substr($LzmaPropertyData, 0, 1)); + #my $LzmaDictSize = unpack ("V", substr($LzmaPropertyData, 1, 4)); + + # Create an LZMA_Alone header + #$self->pushBack($LzmaPropertyData . + # $uncompressedLength->getPacked_V64()); + + if (! $streamingMode) { + *$self->{ZipData}{CompressedLen}->subtract(4 + $LzmaPropertiesSize) ; + *$self->{CompressedInputLengthRemaining} = + *$self->{CompressedInputLength} = *$self->{ZipData}{CompressedLen}->get64bit(); + } + + my $obj = + IO::Uncompress::Adapter::UnLzma::mkUncompZipObject($LzmaPropertyData); + + *$self->{Uncomp} = $obj; + } elsif ($compressedMethod == ZIP_CM_STORE) { # TODO -- add support for reading uncompressed @@ -746,7 +754,7 @@ sub filterUncompressed *$self->{ZipData}{CRC32} = *$self->{Uncomp}->crc32() ; } else { - *$self->{ZipData}{CRC32} = crc32(${$_[0]}, *$self->{ZipData}{CRC32}); + *$self->{ZipData}{CRC32} = crc32(${$_[0]}, *$self->{ZipData}{CRC32}, $_[1]); } } @@ -772,6 +780,262 @@ sub _dosToUnixTime return $time_t; } +#sub scanCentralDirectory +#{ +# # Use cases +# # 1 32-bit CD +# # 2 64-bit CD +# +# my $self = shift ; +# +# my @CD = (); +# my $offset = $self->findCentralDirectoryOffset(); +# +# return 0 +# if ! defined $offset; +# +# $self->smarkSeek($offset, 0, SEEK_SET) ; +# +# # Now walk the Central Directory Records +# my $buffer ; +# while ($self->smartReadExact(\$buffer, 46) && +# unpack("V", $buffer) == ZIP_CENTRAL_HDR_SIG) { +# +# my $compressedLength = unpack ("V", substr($buffer, 20, 4)); +# my $filename_length = unpack ("v", substr($buffer, 28, 2)); +# my $extra_length = unpack ("v", substr($buffer, 30, 2)); +# my $comment_length = unpack ("v", substr($buffer, 32, 2)); +# +# $self->smarkSeek($filename_length + $extra_length + $comment_length, 0, SEEK_CUR) +# if $extra_length || $comment_length || $filename_length; +# push @CD, $compressedLength ; +# } +# +#} +# +#sub findCentralDirectoryOffset +#{ +# my $self = shift ; +# +# # Most common use-case is where there is no comment, so +# # know exactly where the end of central directory record +# # should be. +# +# $self->smarkSeek(-22, 0, SEEK_END) ; +# +# my $buffer; +# $self->smartReadExact(\$buffer, 22) ; +# +# my $zip64 = 0; +# my $centralDirOffset ; +# if ( unpack("V", $buffer) == ZIP_END_CENTRAL_HDR_SIG ) { +# $centralDirOffset = unpack ("V", substr($buffer, 16, 2)); +# } +# else { +# die "xxxx"; +# } +# +# return $centralDirOffset ; +#} +# +#sub is84BitCD +#{ +# # TODO +# my $self = shift ; +#} + + +sub skip +{ + my $self = shift; + my $size = shift; + + use Fcntl qw(SEEK_CUR); + if (ref $size eq 'U64') { + $self->smartSeek($size->get64bit(), SEEK_CUR); + } + else { + $self->smartSeek($size, SEEK_CUR); + } + +} + + +sub scanCentralDirectory +{ + my $self = shift; + + my $here = $self->tell(); + + # Use cases + # 1 32-bit CD + # 2 64-bit CD + + my @CD = (); + my $offset = $self->findCentralDirectoryOffset(); + + return () + if ! defined $offset; + + $self->smarkSeek($offset, 0, SEEK_SET) ; + + # Now walk the Central Directory Records + my $buffer ; + while ($self->smartReadExact(\$buffer, 46) && + unpack("V", $buffer) == ZIP_CENTRAL_HDR_SIG) { + + my $compressedLength = unpack("V", substr($buffer, 20, 4)); + my $uncompressedLength = unpack("V", substr($buffer, 24, 4)); + my $filename_length = unpack("v", substr($buffer, 28, 2)); + my $extra_length = unpack("v", substr($buffer, 30, 2)); + my $comment_length = unpack("v", substr($buffer, 32, 2)); + + $self->skip($filename_length ) ; + + my $v64 = new U64 $compressedLength ; + + if (U64::full32 $compressedLength ) { + $self->smartReadExact(\$buffer, $extra_length) ; + die "xxx $offset $comment_length $filename_length $extra_length" . length($buffer) + if length($buffer) != $extra_length; + my $got = $self->get64Extra($buffer, U64::full32 $uncompressedLength); + + # If not Zip64 extra field, assume size is 0xFFFFFFFF + $v64 = $got if defined $got; + } + else { + $self->skip($extra_length) ; + } + + $self->skip($comment_length ) ; + + push @CD, $v64 ; + } + + $self->smartSeek($here, 0, SEEK_SET) ; + + return @CD; +} + +sub get64Extra +{ + my $self = shift ; + + my $buffer = shift; + my $is_uncomp = shift ; + + my $extra = IO::Compress::Zlib::Extra::findID(0x0001, $buffer); + + if (! defined $extra) + { + return undef; + } + else + { + my $u64 = U64::newUnpack_V64(substr($extra, $is_uncomp ? 8 : 0)) ; + return $u64; + } +} + +sub offsetFromZip64 +{ + my $self = shift ; + my $here = shift; + + $self->smartSeek($here - 20, 0, SEEK_SET) + or die "xx $!" ; + + my $buffer; + my $got = 0; + $self->smartReadExact(\$buffer, 20) + or die "xxx $here $got $!" ; + + if ( unpack("V", $buffer) == ZIP64_END_CENTRAL_LOC_HDR_SIG ) { + my $cd64 = U64::Value_VV64 substr($buffer, 8, 8); + + $self->smartSeek($cd64, 0, SEEK_SET) ; + + $self->smartReadExact(\$buffer, 4) + or die "xxx" ; + + if ( unpack("V", $buffer) == ZIP64_END_CENTRAL_REC_HDR_SIG ) { + + $self->smartReadExact(\$buffer, 8) + or die "xxx" ; + my $size = U64::Value_VV64($buffer); + $self->smartReadExact(\$buffer, $size) + or die "xxx" ; + + my $cd64 = U64::Value_VV64 substr($buffer, 36, 8); + + return $cd64 ; + } + + die "zzz"; + } + + die "zzz"; +} + +use constant Pack_ZIP_END_CENTRAL_HDR_SIG => pack("V", ZIP_END_CENTRAL_HDR_SIG); + +sub findCentralDirectoryOffset +{ + my $self = shift ; + + # Most common use-case is where there is no comment, so + # know exactly where the end of central directory record + # should be. + + $self->smartSeek(-22, 0, SEEK_END) ; + my $here = $self->tell(); + + my $buffer; + $self->smartReadExact(\$buffer, 22) + or die "xxx" ; + + my $zip64 = 0; + my $centralDirOffset ; + if ( unpack("V", $buffer) == ZIP_END_CENTRAL_HDR_SIG ) { + $centralDirOffset = unpack("V", substr($buffer, 16, 4)); + } + else { + $self->smartSeek(0, 0, SEEK_END) ; + + my $fileLen = $self->tell(); + my $want = 0 ; + + while(1) { + $want += 1024; + my $seekTo = $fileLen - $want; + if ($seekTo < 0 ) { + $seekTo = 0; + $want = $fileLen ; + } + $self->smartSeek( $seekTo, 0, SEEK_SET) + or die "xxx $!" ; + my $got; + $self->smartReadExact($buffer, $want) + or die "xxx " ; + my $pos = rindex( $buffer, Pack_ZIP_END_CENTRAL_HDR_SIG); + + if ($pos >= 0) { + #$here = $self->tell(); + $here = $seekTo + $pos ; + $centralDirOffset = unpack("V", substr($buffer, $pos + 16, 4)); + last ; + } + + return undef + if $want == $fileLen; + } + } + + $centralDirOffset = $self->offsetFromZip64($here) + if U64::full32 $centralDirOffset ; + + return $centralDirOffset ; +} 1; |