exiftool-vendored.exe 12.80.0 → 12.82.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/bin/exiftool.exe +0 -0
- package/bin/exiftool_files/Changes +44 -0
- package/bin/exiftool_files/Licenses_Strawberry_Perl.zip +0 -0
- package/bin/exiftool_files/README +3 -2
- package/bin/exiftool_files/exiftool.pl +36 -14
- package/bin/exiftool_files/lib/Archive/Zip/Archive.pm +399 -65
- package/bin/exiftool_files/lib/Archive/Zip/DirectoryMember.pm +1 -1
- package/bin/exiftool_files/lib/Archive/Zip/FileMember.pm +1 -1
- package/bin/exiftool_files/lib/Archive/Zip/Member.pm +499 -195
- package/bin/exiftool_files/lib/Archive/Zip/NewFileMember.pm +1 -1
- package/bin/exiftool_files/lib/Archive/Zip/StringMember.pm +2 -2
- package/bin/exiftool_files/lib/Archive/Zip/ZipFileMember.pm +79 -20
- package/bin/exiftool_files/lib/Archive/Zip.pm +179 -29
- package/bin/exiftool_files/lib/AutoLoader.pm +453 -0
- package/bin/exiftool_files/lib/B/Deparse.pm +209 -137
- package/bin/exiftool_files/lib/B.pm +1 -1
- package/bin/exiftool_files/lib/Benchmark.pm +1123 -0
- package/bin/exiftool_files/lib/Class/Struct.pm +2 -2
- package/bin/exiftool_files/lib/Compress/Raw/Bzip2.pm +14 -9
- package/bin/exiftool_files/lib/Compress/Raw/Lzma.pm +982 -0
- package/bin/exiftool_files/lib/Compress/Raw/Zlib.pm +91 -86
- package/bin/exiftool_files/lib/Compress/Zlib.pm +105 -100
- package/bin/exiftool_files/lib/Config.pm +9 -9
- package/bin/exiftool_files/lib/Config_heavy.pl +36 -33
- package/bin/exiftool_files/lib/CryptX.pm +2 -82
- package/bin/exiftool_files/lib/Data/Dumper.pm +2 -2
- package/bin/exiftool_files/lib/Digest/MD5.pm +12 -9
- package/bin/exiftool_files/lib/Digest/Perl/MD5.pm +1 -191
- package/bin/exiftool_files/lib/Digest/base.pm +26 -20
- package/bin/exiftool_files/lib/DynaLoader.pm +7 -4
- package/bin/exiftool_files/lib/Encode.pm +3 -3
- package/bin/exiftool_files/lib/Errno.pm +13 -13
- package/bin/exiftool_files/lib/Exporter/Heavy.pm +2 -2
- package/bin/exiftool_files/lib/Exporter.pm +1 -1
- package/bin/exiftool_files/lib/ExtUtils/Command/MM.pm +323 -0
- package/bin/exiftool_files/lib/ExtUtils/Command.pm +382 -0
- package/bin/exiftool_files/lib/File/Find.pm +1 -1
- package/bin/exiftool_files/lib/File/Glob.pm +1 -8
- package/bin/exiftool_files/lib/File/GlobMapper.pm +2 -2
- package/bin/exiftool_files/lib/File/HomeDir/Darwin/Carbon.pm +2 -40
- package/bin/exiftool_files/lib/File/HomeDir/Darwin/Cocoa.pm +2 -34
- package/bin/exiftool_files/lib/File/HomeDir/Darwin.pm +2 -28
- package/bin/exiftool_files/lib/File/HomeDir/Driver.pm +2 -35
- package/bin/exiftool_files/lib/File/HomeDir/FreeDesktop.pm +2 -62
- package/bin/exiftool_files/lib/File/HomeDir/MacOS9.pm +2 -53
- package/bin/exiftool_files/lib/File/HomeDir/Test.pm +2 -43
- package/bin/exiftool_files/lib/File/HomeDir/Unix.pm +2 -53
- package/bin/exiftool_files/lib/File/HomeDir/Windows.pm +2 -69
- package/bin/exiftool_files/lib/File/HomeDir.pm +5 -416
- package/bin/exiftool_files/lib/File/Path.pm +3 -3
- package/bin/exiftool_files/lib/File/Spec/Win32.pm +2 -2
- package/bin/exiftool_files/lib/File/Temp.pm +70 -35
- package/bin/exiftool_files/lib/File/Which.pm +1 -240
- package/bin/exiftool_files/lib/File/stat.pm +3 -2
- package/bin/exiftool_files/lib/IO/Compress/Adapter/Bzip2.pm +16 -17
- package/bin/exiftool_files/lib/IO/Compress/Adapter/Deflate.pm +19 -20
- package/bin/exiftool_files/lib/IO/Compress/Base/Common.pm +5 -5
- package/bin/exiftool_files/lib/IO/Compress/Base.pm +35 -26
- package/bin/exiftool_files/lib/IO/Compress/Brotli.pm +159 -0
- package/bin/exiftool_files/lib/IO/Compress/Bzip2.pm +50 -25
- package/bin/exiftool_files/lib/IO/Compress/Gzip/Constants.pm +6 -6
- package/bin/exiftool_files/lib/IO/Compress/Gzip.pm +58 -32
- package/bin/exiftool_files/lib/IO/Compress/RawDeflate.pm +63 -38
- package/bin/exiftool_files/lib/IO/Compress/Zlib/Extra.pm +20 -20
- package/bin/exiftool_files/lib/IO/Dir.pm +1 -1
- package/bin/exiftool_files/lib/IO/File.pm +1 -1
- package/bin/exiftool_files/lib/IO/Handle.pm +1 -21
- package/bin/exiftool_files/lib/IO/Pipe.pm +1 -1
- package/bin/exiftool_files/lib/IO/Seekable.pm +1 -1
- package/bin/exiftool_files/lib/IO/Select.pm +16 -2
- package/bin/exiftool_files/lib/IO/Socket/INET.pm +14 -9
- package/bin/exiftool_files/lib/IO/Socket/UNIX.pm +17 -1
- package/bin/exiftool_files/lib/IO/Socket.pm +474 -126
- package/bin/exiftool_files/lib/IO/String.pm +425 -0
- package/bin/exiftool_files/lib/IO/Uncompress/Adapter/Inflate.pm +13 -14
- package/bin/exiftool_files/lib/IO/Uncompress/Base.pm +142 -132
- package/bin/exiftool_files/lib/IO/Uncompress/Brotli.pm +119 -0
- package/bin/exiftool_files/lib/IO/Uncompress/Gunzip.pm +43 -37
- package/bin/exiftool_files/lib/IO/Uncompress/RawInflate.pm +49 -43
- package/bin/exiftool_files/lib/IO.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +44 -31
- package/bin/exiftool_files/lib/Image/ExifTool/CanonVRD.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +20 -7
- package/bin/exiftool_files/lib/Image/ExifTool/GM.pm +543 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Geolocation.pm +332 -149
- package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +9 -4
- package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +32 -4
- package/bin/exiftool_files/lib/Image/ExifTool/MakerNotes.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Microsoft.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +331 -22
- package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +55 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +1 -0
- package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +21 -3
- package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +40 -24
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +61 -30
- package/bin/exiftool_files/lib/Image/ExifTool/README +2 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +4815 -4775
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +931 -617
- package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +30 -8
- package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +10 -4
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +4 -2
- package/bin/exiftool_files/lib/Image/ExifTool.pm +77 -41
- package/bin/exiftool_files/lib/Image/ExifTool.pod +24 -11
- package/bin/exiftool_files/lib/List/Util.pm +97 -8
- package/bin/exiftool_files/lib/MIME/Base64.pm +5 -5
- package/bin/exiftool_files/lib/MIME/Charset/_Compat.pm +106 -0
- package/bin/exiftool_files/lib/MIME/Charset.pm +1303 -0
- package/bin/exiftool_files/lib/Math/BigFloat.pm +444 -27
- package/bin/exiftool_files/lib/Math/BigInt/Calc.pm +296 -313
- package/bin/exiftool_files/lib/Math/BigInt/FastCalc.pm +1 -1
- package/bin/exiftool_files/lib/Math/BigInt/GMP.pm +2 -115
- package/bin/exiftool_files/lib/Math/BigInt/LTM.pm +2 -24
- package/bin/exiftool_files/lib/Math/BigInt/Lib.pm +61 -32
- package/bin/exiftool_files/lib/Math/BigInt.pm +292 -107
- package/bin/exiftool_files/lib/POSIX.pm +1 -1
- package/bin/exiftool_files/lib/PerlIO/scalar.pm +41 -0
- package/bin/exiftool_files/lib/PerlIO.pm +397 -0
- package/bin/exiftool_files/lib/Portable/CPAN.pm +94 -94
- package/bin/exiftool_files/lib/Portable/Config.pm +94 -94
- package/bin/exiftool_files/lib/Portable/FileSpec.pm +180 -180
- package/bin/exiftool_files/lib/Portable/HomeDir.pm +110 -110
- package/bin/exiftool_files/lib/Portable/LoadYaml.pm +430 -430
- package/bin/exiftool_files/lib/Portable/minicpan.pm +55 -55
- package/bin/exiftool_files/lib/Portable.pm +246 -320
- package/bin/exiftool_files/lib/Scalar/Util.pm +9 -4
- package/bin/exiftool_files/lib/Socket.pm +16 -12
- package/bin/exiftool_files/lib/Storable.pm +1444 -1441
- package/bin/exiftool_files/lib/TAP/Base.pm +133 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Base.pm +467 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Color.pm +116 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Console/ParallelSession.pm +201 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Console/Session.pm +205 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Console.pm +100 -0
- package/bin/exiftool_files/lib/TAP/Formatter/File/Session.pm +95 -0
- package/bin/exiftool_files/lib/TAP/Formatter/File.pm +56 -0
- package/bin/exiftool_files/lib/TAP/Formatter/Session.pm +220 -0
- package/bin/exiftool_files/lib/TAP/Harness/Beyond.pod +426 -0
- package/bin/exiftool_files/lib/TAP/Harness/Env.pm +215 -0
- package/bin/exiftool_files/lib/TAP/Harness.pm +1054 -0
- package/bin/exiftool_files/lib/TAP/Object.pm +155 -0
- package/bin/exiftool_files/lib/TAP/Parser/Aggregator.pm +414 -0
- package/bin/exiftool_files/lib/TAP/Parser/Grammar.pm +584 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator/Array.pm +100 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator/Process.pm +378 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator/Stream.pm +116 -0
- package/bin/exiftool_files/lib/TAP/Parser/Iterator.pm +162 -0
- package/bin/exiftool_files/lib/TAP/Parser/IteratorFactory.pm +339 -0
- package/bin/exiftool_files/lib/TAP/Parser/Multiplexer.pm +194 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Bailout.pm +62 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Comment.pm +60 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Plan.pm +119 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Pragma.pm +62 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Test.pm +271 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Unknown.pm +48 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/Version.pm +62 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result/YAML.pm +61 -0
- package/bin/exiftool_files/lib/TAP/Parser/Result.pm +297 -0
- package/bin/exiftool_files/lib/TAP/Parser/ResultFactory.pm +183 -0
- package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Job.pm +127 -0
- package/bin/exiftool_files/lib/TAP/Parser/Scheduler/Spinner.pm +61 -0
- package/bin/exiftool_files/lib/TAP/Parser/Scheduler.pm +448 -0
- package/bin/exiftool_files/lib/TAP/Parser/Source.pm +381 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Executable.pm +184 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/File.pm +136 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Handle.pm +124 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/Perl.pm +370 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler/RawTAP.pm +130 -0
- package/bin/exiftool_files/lib/TAP/Parser/SourceHandler.pm +191 -0
- package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Reader.pm +332 -0
- package/bin/exiftool_files/lib/TAP/Parser/YAMLish/Writer.pm +254 -0
- package/bin/exiftool_files/lib/TAP/Parser.pm +1931 -0
- package/bin/exiftool_files/lib/Test/Builder/Formatter.pm +107 -0
- package/bin/exiftool_files/lib/Test/Builder/IO/Scalar.pm +659 -0
- package/bin/exiftool_files/lib/Test/Builder/Module.pm +182 -0
- package/bin/exiftool_files/lib/Test/Builder/Tester/Color.pm +51 -0
- package/bin/exiftool_files/lib/Test/Builder/Tester.pm +675 -0
- package/bin/exiftool_files/lib/Test/Builder/TodoDiag.pm +68 -0
- package/bin/exiftool_files/lib/Test/Builder.pm +2653 -0
- package/bin/exiftool_files/lib/Test/Harness.pm +618 -0
- package/bin/exiftool_files/lib/Test/More.pm +1997 -0
- package/bin/exiftool_files/lib/Test/Simple.pm +220 -0
- package/bin/exiftool_files/lib/Test/Tester/Capture.pm +241 -0
- package/bin/exiftool_files/lib/Test/Tester/CaptureRunner.pm +79 -0
- package/bin/exiftool_files/lib/Test/Tester/Delegate.pm +45 -0
- package/bin/exiftool_files/lib/Test/Tester.pm +695 -0
- package/bin/exiftool_files/lib/Test/Tutorial.pod +618 -0
- package/bin/exiftool_files/lib/Test/use/ok.pm +64 -0
- package/bin/exiftool_files/lib/Text/ParseWords.pm +303 -0
- package/bin/exiftool_files/lib/Tie/StdHandle.pm +2 -2
- package/bin/exiftool_files/lib/Time/HiRes.pm +73 -68
- package/bin/exiftool_files/lib/Time/Local.pm +82 -35
- package/bin/exiftool_files/lib/Time/Piece.pm +19 -4
- package/bin/exiftool_files/lib/Time/Seconds.pm +1 -1
- package/bin/exiftool_files/lib/UNIVERSAL.pm +203 -0
- package/bin/exiftool_files/lib/Unicode/GCString.pm +60 -0
- package/bin/exiftool_files/lib/Unicode/LineBreak/Constants.pm +68 -0
- package/bin/exiftool_files/lib/Unicode/LineBreak.pm +248 -0
- package/bin/exiftool_files/lib/Win32/API/Struct.pm +1 -177
- package/bin/exiftool_files/lib/Win32/API/Type.pm +1 -100
- package/bin/exiftool_files/lib/Win32/API.pm +1 -830
- package/bin/exiftool_files/lib/Win32/FindFile.pm +2 -123
- package/bin/exiftool_files/lib/Win32.pm +213 -89
- package/bin/exiftool_files/lib/Win32API/File.pm +1 -1
- package/bin/exiftool_files/lib/auto/B/B.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Bzip2/Bzip2.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/Lzma.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Lzma/autosplit.ix +3 -0
- package/bin/exiftool_files/lib/auto/Compress/Raw/Zlib/Zlib.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/CryptX/CryptX.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Cwd/Cwd.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Data/Dumper/Dumper.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Digest/MD5/MD5.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Digest/SHA/SHA.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Encode/Encode.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Fcntl/Fcntl.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/File/Glob/Glob.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/IO/Compress/Brotli/Brotli.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/IO/IO.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/List/Util/Util.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/MIME/Base64/Base64.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Math/BigInt/FastCalc/FastCalc.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Math/BigInt/GMP/GMP.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/POSIX/POSIX.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/PerlIO/scalar/scalar.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Socket/Socket.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Storable/Storable.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Time/HiRes/HiRes.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Time/Piece/Piece.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Unicode/LineBreak/LineBreak.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32/API/API.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32/FindFile/FindFile.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32/Win32.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/Win32API/File/File.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/mro/mro.xs.dll +0 -0
- package/bin/exiftool_files/lib/auto/re/re.xs.dll +0 -0
- package/bin/exiftool_files/lib/feature.pm +49 -17
- package/bin/exiftool_files/lib/mro.pm +4 -20
- package/bin/exiftool_files/lib/overload.pm +15 -15
- package/bin/exiftool_files/lib/parent.pm +10 -2
- package/bin/exiftool_files/lib/re.pm +91 -33
- package/bin/exiftool_files/lib/warnings.pm +17 -6
- package/bin/exiftool_files/libgcc_s_seh-1.dll +0 -0
- package/bin/exiftool_files/liblzma-5__.dll +0 -0
- package/bin/exiftool_files/libstdc++-6.dll +0 -0
- package/bin/exiftool_files/libwinpthread-1.dll +0 -0
- package/bin/exiftool_files/perl.exe +0 -0
- package/bin/exiftool_files/perl532.dll +0 -0
- package/package.json +7 -5
- package/bin/exiftool_files/libgcc_s_dw2-1.dll +0 -0
- package/bin/exiftool_files/perl530.dll +0 -0
|
@@ -14,7 +14,7 @@ use Encode qw(encode_utf8 decode_utf8);
|
|
|
14
14
|
use vars qw( $VERSION @ISA );
|
|
15
15
|
|
|
16
16
|
BEGIN {
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.68';
|
|
18
18
|
@ISA = qw( Archive::Zip );
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -32,14 +32,27 @@ our $UNTAINT = qr/\A(.+)\z/;
|
|
|
32
32
|
|
|
33
33
|
sub new {
|
|
34
34
|
my $class = shift;
|
|
35
|
+
# Info-Zip 3.0 (I guess) seems to use the following values
|
|
36
|
+
# for the version fields in the zip64 EOCD record:
|
|
37
|
+
#
|
|
38
|
+
# version made by:
|
|
39
|
+
# 30 (plus upper byte indicating host system)
|
|
40
|
+
#
|
|
41
|
+
# version needed to extract:
|
|
42
|
+
# 45
|
|
35
43
|
my $self = bless(
|
|
36
44
|
{
|
|
37
|
-
'
|
|
38
|
-
'
|
|
45
|
+
'zip64' => 0,
|
|
46
|
+
'desiredZip64Mode' => ZIP64_AS_NEEDED,
|
|
47
|
+
'versionMadeBy' => 0,
|
|
48
|
+
'versionNeededToExtract' => 0,
|
|
49
|
+
'diskNumber' => 0,
|
|
50
|
+
'diskNumberWithStartOfCentralDirectory' =>
|
|
51
|
+
0,
|
|
39
52
|
'numberOfCentralDirectoriesOnThisDisk' =>
|
|
40
53
|
0, # should be # of members
|
|
41
|
-
'numberOfCentralDirectories'
|
|
42
|
-
'centralDirectorySize'
|
|
54
|
+
'numberOfCentralDirectories' => 0, # should be # of members
|
|
55
|
+
'centralDirectorySize' => 0, # must re-compute on write
|
|
43
56
|
'centralDirectoryOffsetWRTStartingDiskNumber' =>
|
|
44
57
|
0, # must re-compute
|
|
45
58
|
'writeEOCDOffset' => 0,
|
|
@@ -93,6 +106,28 @@ sub membersMatching {
|
|
|
93
106
|
return grep { $_->fileName() =~ /$pattern/ } $self->members();
|
|
94
107
|
}
|
|
95
108
|
|
|
109
|
+
sub zip64 {
|
|
110
|
+
shift->{'zip64'};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
sub desiredZip64Mode {
|
|
114
|
+
my $self = shift;
|
|
115
|
+
my $desiredZip64Mode = $self->{'desiredZip64Mode'};
|
|
116
|
+
if (@_) {
|
|
117
|
+
$self->{'desiredZip64Mode'} =
|
|
118
|
+
ref($_[0]) eq 'HASH' ? shift->{desiredZip64Mode} : shift;
|
|
119
|
+
}
|
|
120
|
+
return $desiredZip64Mode;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
sub versionMadeBy {
|
|
124
|
+
shift->{'versionMadeBy'};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
sub versionNeededToExtract {
|
|
128
|
+
shift->{'versionNeededToExtract'};
|
|
129
|
+
}
|
|
130
|
+
|
|
96
131
|
sub diskNumber {
|
|
97
132
|
shift->{'diskNumber'};
|
|
98
133
|
}
|
|
@@ -234,9 +269,9 @@ sub addMember {
|
|
|
234
269
|
my $self = shift;
|
|
235
270
|
my $newMember = (ref($_[0]) eq 'HASH') ? shift->{member} : shift;
|
|
236
271
|
push(@{$self->{'members'}}, $newMember) if $newMember;
|
|
237
|
-
if($newMember && ($newMember->{bitFlag} & 0x800)
|
|
272
|
+
if($newMember && ($newMember->{bitFlag} & 0x800)
|
|
238
273
|
&& !utf8::is_utf8($newMember->{fileName})){
|
|
239
|
-
$newMember->{fileName} = Encode::decode_utf8(
|
|
274
|
+
$newMember->{fileName} = Encode::decode_utf8($newMember->{fileName});
|
|
240
275
|
}
|
|
241
276
|
return $newMember;
|
|
242
277
|
}
|
|
@@ -269,7 +304,7 @@ sub addFile {
|
|
|
269
304
|
} else {
|
|
270
305
|
$self->addMember($newMember);
|
|
271
306
|
}
|
|
272
|
-
|
|
307
|
+
|
|
273
308
|
return $newMember;
|
|
274
309
|
}
|
|
275
310
|
|
|
@@ -318,7 +353,7 @@ sub addDirectory {
|
|
|
318
353
|
} else {
|
|
319
354
|
$self->addMember($newMember);
|
|
320
355
|
}
|
|
321
|
-
|
|
356
|
+
|
|
322
357
|
return $newMember;
|
|
323
358
|
}
|
|
324
359
|
|
|
@@ -366,10 +401,23 @@ sub contents {
|
|
|
366
401
|
($member, $newContents) = @_;
|
|
367
402
|
}
|
|
368
403
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
404
|
+
my ($contents, $status) = (undef, AZ_OK);
|
|
405
|
+
if ($status == AZ_OK) {
|
|
406
|
+
$status = _error('No member name given') unless defined($member);
|
|
407
|
+
}
|
|
408
|
+
if ($status == AZ_OK && ! ref($member)) {
|
|
409
|
+
my $memberName = $member;
|
|
410
|
+
$member = $self->memberNamed($memberName);
|
|
411
|
+
$status = _error('No member named $memberName') unless defined($member);
|
|
412
|
+
}
|
|
413
|
+
if ($status == AZ_OK) {
|
|
414
|
+
($contents, $status) = $member->contents($newContents);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return
|
|
418
|
+
wantarray
|
|
419
|
+
? ($contents, $status)
|
|
420
|
+
: $contents;
|
|
373
421
|
}
|
|
374
422
|
|
|
375
423
|
sub writeToFileNamed {
|
|
@@ -385,11 +433,11 @@ sub writeToFileNamed {
|
|
|
385
433
|
}
|
|
386
434
|
my ($status, $fh) = _newFileHandle($fileName, 'w');
|
|
387
435
|
return _ioError("Can't open $fileName for write") unless $status;
|
|
388
|
-
|
|
436
|
+
$status = $self->writeToFileHandle($fh, 1);
|
|
389
437
|
$fh->close();
|
|
390
438
|
$fh = undef;
|
|
391
439
|
|
|
392
|
-
return $
|
|
440
|
+
return $status;
|
|
393
441
|
}
|
|
394
442
|
|
|
395
443
|
# It is possible to write data to the FH before calling this,
|
|
@@ -415,19 +463,63 @@ sub writeToFileHandle {
|
|
|
415
463
|
my $offset = $fhIsSeekable ? $fh->tell() : 0;
|
|
416
464
|
$offset = 0 if $offset < 0;
|
|
417
465
|
|
|
466
|
+
# (Re-)set the "was-successfully-written" flag so that the
|
|
467
|
+
# contract advertised in the documentation ("that member and
|
|
468
|
+
# *all following it* will return false from wasWritten()")
|
|
469
|
+
# also holds for members written more than once.
|
|
470
|
+
#
|
|
471
|
+
# Not sure whether that mechanism works, anyway. If method
|
|
472
|
+
# $member->_writeToFileHandle fails with an error below and
|
|
473
|
+
# user continues with calling $zip->writeCentralDirectory
|
|
474
|
+
# manually, we should end up with the following picture
|
|
475
|
+
# unless the user seeks back to writeCentralDirectoryOffset:
|
|
476
|
+
#
|
|
477
|
+
# ...
|
|
478
|
+
# [last successfully written member]
|
|
479
|
+
# <- writeCentralDirectoryOffset points here
|
|
480
|
+
# [half-written member junk with unknown size]
|
|
481
|
+
# [central directory entry 0]
|
|
482
|
+
# ...
|
|
418
483
|
foreach my $member ($self->members()) {
|
|
419
|
-
|
|
484
|
+
$member->{'wasWritten'} = 0;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
foreach my $member ($self->members()) {
|
|
488
|
+
|
|
489
|
+
# (Re-)set object member zip64 flag. Here is what
|
|
490
|
+
# happens next to that flag:
|
|
491
|
+
#
|
|
492
|
+
# $member->_writeToFileHandle
|
|
493
|
+
# Determines a local flag value depending on
|
|
494
|
+
# necessity and user desire and ors it to
|
|
495
|
+
# the object member
|
|
496
|
+
# $member->_writeLocalFileHeader
|
|
497
|
+
# Queries the object member to write appropriate
|
|
498
|
+
# local header
|
|
499
|
+
# $member->_writeDataDescriptor
|
|
500
|
+
# Queries the object member to write appropriate
|
|
501
|
+
# data descriptor
|
|
502
|
+
# $member->_writeCentralDirectoryFileHeader
|
|
503
|
+
# Determines a local flag value depending on
|
|
504
|
+
# necessity and user desire. Writes a central
|
|
505
|
+
# directory header appropriate to the local flag.
|
|
506
|
+
# Ors the local flag to the object member.
|
|
507
|
+
$member->{'zip64'} = 0;
|
|
508
|
+
|
|
509
|
+
my ($status, $memberSize) =
|
|
510
|
+
$member->_writeToFileHandle($fh, $fhIsSeekable, $offset,
|
|
511
|
+
$self->desiredZip64Mode());
|
|
420
512
|
$member->endRead();
|
|
421
|
-
return $
|
|
422
|
-
|
|
423
|
-
$offset +=
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
# changed this so it reflects the last successful position
|
|
513
|
+
return $status if $status != AZ_OK;
|
|
514
|
+
|
|
515
|
+
$offset += $memberSize;
|
|
516
|
+
|
|
517
|
+
# Change this so it reflects write status and last
|
|
518
|
+
# successful position
|
|
519
|
+
$member->{'wasWritten'} = 1;
|
|
429
520
|
$self->{'writeCentralDirectoryOffset'} = $offset;
|
|
430
521
|
}
|
|
522
|
+
|
|
431
523
|
return $self->writeCentralDirectory($fh);
|
|
432
524
|
}
|
|
433
525
|
|
|
@@ -500,20 +592,83 @@ sub _writeEOCDOffset {
|
|
|
500
592
|
|
|
501
593
|
# Expects to have _writeEOCDOffset() set
|
|
502
594
|
sub _writeEndOfCentralDirectory {
|
|
503
|
-
my ($self, $fh) = @_;
|
|
595
|
+
my ($self, $fh, $membersZip64) = @_;
|
|
596
|
+
|
|
597
|
+
my $zip64 = 0;
|
|
598
|
+
my $versionMadeBy = $self->versionMadeBy();
|
|
599
|
+
my $versionNeededToExtract = $self->versionNeededToExtract();
|
|
600
|
+
my $diskNumber = 0;
|
|
601
|
+
my $diskNumberWithStartOfCentralDirectory = 0;
|
|
602
|
+
my $numberOfCentralDirectoriesOnThisDisk = $self->numberOfMembers();
|
|
603
|
+
my $numberOfCentralDirectories = $self->numberOfMembers();
|
|
604
|
+
my $centralDirectorySize =
|
|
605
|
+
$self->_writeEOCDOffset() - $self->_writeCentralDirectoryOffset();
|
|
606
|
+
my $centralDirectoryOffsetWRTStartingDiskNumber =
|
|
607
|
+
$self->_writeCentralDirectoryOffset();
|
|
608
|
+
my $zipfileCommentLength = length($self->zipfileComment());
|
|
609
|
+
|
|
610
|
+
my $eocdDataZip64 = 0;
|
|
611
|
+
$eocdDataZip64 ||= $numberOfCentralDirectoriesOnThisDisk > 0xffff;
|
|
612
|
+
$eocdDataZip64 ||= $numberOfCentralDirectories > 0xffff;
|
|
613
|
+
$eocdDataZip64 ||= $centralDirectorySize > 0xffffffff;
|
|
614
|
+
$eocdDataZip64 ||= $centralDirectoryOffsetWRTStartingDiskNumber > 0xffffffff;
|
|
615
|
+
|
|
616
|
+
if ( $membersZip64
|
|
617
|
+
|| $eocdDataZip64
|
|
618
|
+
|| $self->desiredZip64Mode() == ZIP64_EOCD) {
|
|
619
|
+
return _zip64NotSupported() unless ZIP64_SUPPORTED;
|
|
620
|
+
|
|
621
|
+
$zip64 = 1;
|
|
622
|
+
$versionMadeBy = 45 if ($versionMadeBy == 0);
|
|
623
|
+
$versionNeededToExtract = 45 if ($versionNeededToExtract < 45);
|
|
624
|
+
|
|
625
|
+
$self->_print($fh, ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE_STRING)
|
|
626
|
+
or return _ioError('writing zip64 EOCD record signature');
|
|
627
|
+
|
|
628
|
+
my $record = pack(
|
|
629
|
+
ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_FORMAT,
|
|
630
|
+
ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_LENGTH +
|
|
631
|
+
SIGNATURE_LENGTH - 12,
|
|
632
|
+
$versionMadeBy,
|
|
633
|
+
$versionNeededToExtract,
|
|
634
|
+
$diskNumber,
|
|
635
|
+
$diskNumberWithStartOfCentralDirectory,
|
|
636
|
+
$numberOfCentralDirectoriesOnThisDisk,
|
|
637
|
+
$numberOfCentralDirectories,
|
|
638
|
+
$centralDirectorySize,
|
|
639
|
+
$centralDirectoryOffsetWRTStartingDiskNumber
|
|
640
|
+
);
|
|
641
|
+
$self->_print($fh, $record)
|
|
642
|
+
or return _ioError('writing zip64 EOCD record');
|
|
643
|
+
|
|
644
|
+
$self->_print($fh, ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE_STRING)
|
|
645
|
+
or return _ioError('writing zip64 EOCD locator signature');
|
|
646
|
+
|
|
647
|
+
my $locator = pack(
|
|
648
|
+
ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_FORMAT,
|
|
649
|
+
0,
|
|
650
|
+
$self->_writeEOCDOffset(),
|
|
651
|
+
1
|
|
652
|
+
);
|
|
653
|
+
$self->_print($fh, $locator)
|
|
654
|
+
or return _ioError('writing zip64 EOCD locator');
|
|
655
|
+
}
|
|
504
656
|
|
|
505
657
|
$self->_print($fh, END_OF_CENTRAL_DIRECTORY_SIGNATURE_STRING)
|
|
506
658
|
or return _ioError('writing EOCD Signature');
|
|
507
|
-
my $zipfileCommentLength = length($self->zipfileComment());
|
|
508
659
|
|
|
509
660
|
my $header = pack(
|
|
510
661
|
END_OF_CENTRAL_DIRECTORY_FORMAT,
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
$
|
|
514
|
-
|
|
515
|
-
$
|
|
516
|
-
|
|
662
|
+
$diskNumber,
|
|
663
|
+
$diskNumberWithStartOfCentralDirectory,
|
|
664
|
+
$numberOfCentralDirectoriesOnThisDisk > 0xffff
|
|
665
|
+
? 0xffff : $numberOfCentralDirectoriesOnThisDisk,
|
|
666
|
+
$numberOfCentralDirectories > 0xffff
|
|
667
|
+
? 0xffff : $numberOfCentralDirectories,
|
|
668
|
+
$centralDirectorySize > 0xffffffff
|
|
669
|
+
? 0xffffffff : $centralDirectorySize,
|
|
670
|
+
$centralDirectoryOffsetWRTStartingDiskNumber > 0xffffffff
|
|
671
|
+
? 0xffffffff : $centralDirectoryOffsetWRTStartingDiskNumber,
|
|
517
672
|
$zipfileCommentLength
|
|
518
673
|
);
|
|
519
674
|
$self->_print($fh, $header)
|
|
@@ -522,6 +677,12 @@ sub _writeEndOfCentralDirectory {
|
|
|
522
677
|
$self->_print($fh, $self->zipfileComment())
|
|
523
678
|
or return _ioError('writing zipfile comment');
|
|
524
679
|
}
|
|
680
|
+
|
|
681
|
+
# Adjust object members related to zip64 format
|
|
682
|
+
$self->{'zip64'} = $zip64;
|
|
683
|
+
$self->{'versionMadeBy'} = $versionMadeBy;
|
|
684
|
+
$self->{'versionNeededToExtract'} = $versionNeededToExtract;
|
|
685
|
+
|
|
525
686
|
return AZ_OK;
|
|
526
687
|
}
|
|
527
688
|
|
|
@@ -545,13 +706,17 @@ sub writeCentralDirectory {
|
|
|
545
706
|
$offset = $self->_writeCentralDirectoryOffset();
|
|
546
707
|
}
|
|
547
708
|
|
|
709
|
+
my $membersZip64 = 0;
|
|
548
710
|
foreach my $member ($self->members()) {
|
|
549
|
-
my $status
|
|
711
|
+
my ($status, $headerSize) =
|
|
712
|
+
$member->_writeCentralDirectoryFileHeader($fh, $self->desiredZip64Mode());
|
|
550
713
|
return $status if $status != AZ_OK;
|
|
551
|
-
$
|
|
714
|
+
$membersZip64 ||= $member->zip64();
|
|
715
|
+
$offset += $headerSize;
|
|
552
716
|
$self->{'writeEOCDOffset'} = $offset;
|
|
553
717
|
}
|
|
554
|
-
|
|
718
|
+
|
|
719
|
+
return $self->_writeEndOfCentralDirectory($fh, $membersZip64);
|
|
555
720
|
}
|
|
556
721
|
|
|
557
722
|
sub read {
|
|
@@ -596,11 +761,12 @@ sub readFromFileHandle {
|
|
|
596
761
|
my $status = $self->_findEndOfCentralDirectory($fh);
|
|
597
762
|
return $status if $status != AZ_OK;
|
|
598
763
|
|
|
599
|
-
my $eocdPosition
|
|
600
|
-
|
|
601
|
-
$status = $self->_readEndOfCentralDirectory($fh);
|
|
764
|
+
my $eocdPosition;
|
|
765
|
+
($status, $eocdPosition) = $self->_readEndOfCentralDirectory($fh, $fileName);
|
|
602
766
|
return $status if $status != AZ_OK;
|
|
603
767
|
|
|
768
|
+
my $zip64 = $self->zip64();
|
|
769
|
+
|
|
604
770
|
$fh->seek($eocdPosition - $self->centralDirectorySize(),
|
|
605
771
|
IO::Seekable::SEEK_SET)
|
|
606
772
|
or return _ioError("Can't seek $fileName");
|
|
@@ -612,22 +778,33 @@ sub readFromFileHandle {
|
|
|
612
778
|
|
|
613
779
|
for (; ;) {
|
|
614
780
|
my $newMember =
|
|
615
|
-
Archive::Zip::Member->_newFromZipFile($fh, $fileName,
|
|
781
|
+
Archive::Zip::Member->_newFromZipFile($fh, $fileName, $zip64,
|
|
616
782
|
$self->eocdOffset());
|
|
617
783
|
my $signature;
|
|
618
784
|
($status, $signature) = _readSignature($fh, $fileName);
|
|
619
785
|
return $status if $status != AZ_OK;
|
|
620
|
-
|
|
786
|
+
if (! $zip64) {
|
|
787
|
+
last if $signature == END_OF_CENTRAL_DIRECTORY_SIGNATURE;
|
|
788
|
+
}
|
|
789
|
+
else {
|
|
790
|
+
last if $signature == ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE;
|
|
791
|
+
}
|
|
621
792
|
$status = $newMember->_readCentralDirectoryFileHeader();
|
|
622
793
|
return $status if $status != AZ_OK;
|
|
623
794
|
$status = $newMember->endRead();
|
|
624
795
|
return $status if $status != AZ_OK;
|
|
625
|
-
|
|
796
|
+
|
|
797
|
+
if ($newMember->isDirectory()) {
|
|
798
|
+
$newMember->_become('Archive::Zip::DirectoryMember');
|
|
799
|
+
# Ensure above call suceeded to avoid future trouble
|
|
800
|
+
$newMember->_ISA('Archive::Zip::DirectoryMember') or
|
|
801
|
+
return $self->_error('becoming Archive::Zip::DirectoryMember');
|
|
802
|
+
}
|
|
626
803
|
|
|
627
804
|
if(($newMember->{bitFlag} & 0x800) && !utf8::is_utf8($newMember->{fileName})){
|
|
628
805
|
$newMember->{fileName} = Encode::decode_utf8($newMember->{fileName});
|
|
629
806
|
}
|
|
630
|
-
|
|
807
|
+
|
|
631
808
|
push(@{$self->{'members'}}, $newMember);
|
|
632
809
|
}
|
|
633
810
|
|
|
@@ -635,14 +812,142 @@ sub readFromFileHandle {
|
|
|
635
812
|
}
|
|
636
813
|
|
|
637
814
|
# Read EOCD, starting from position before signature.
|
|
638
|
-
#
|
|
815
|
+
# Checks for a zip64 EOCD record and uses that if present.
|
|
816
|
+
#
|
|
817
|
+
# Return AZ_OK (in scalar context) or a pair (AZ_OK,
|
|
818
|
+
# $eocdPosition) (in list context) on success:
|
|
819
|
+
# ( $status, $eocdPosition ) = $zip->_readEndOfCentralDirectory( $fh, $fileName );
|
|
820
|
+
# where the returned EOCD position either points to the beginning
|
|
821
|
+
# of the EOCD or to the beginning of the zip64 EOCD record.
|
|
822
|
+
#
|
|
823
|
+
# APPNOTE.TXT as of version 6.3.6 is a bit vague on the
|
|
824
|
+
# "ZIP64(tm) format". It has a lot of conditions like "if an
|
|
825
|
+
# archive is in ZIP64 format", but never explicitly mentions
|
|
826
|
+
# *when* an archive is in that format. (Or at least I haven't
|
|
827
|
+
# found it.)
|
|
828
|
+
#
|
|
829
|
+
# So I decided that an archive is in ZIP64 format if zip64 EOCD
|
|
830
|
+
# locator and zip64 EOCD record are present before the EOCD with
|
|
831
|
+
# the format given in the specification.
|
|
639
832
|
sub _readEndOfCentralDirectory {
|
|
640
|
-
my $self
|
|
641
|
-
my $fh
|
|
833
|
+
my $self = shift;
|
|
834
|
+
my $fh = shift;
|
|
835
|
+
my $fileName = shift;
|
|
836
|
+
|
|
837
|
+
# Remember current position, which is just before the EOCD
|
|
838
|
+
# signature
|
|
839
|
+
my $eocdPosition = $fh->tell();
|
|
840
|
+
|
|
841
|
+
# Reset the zip64 format flag
|
|
842
|
+
$self->{'zip64'} = 0;
|
|
843
|
+
my $zip64EOCDPosition;
|
|
844
|
+
|
|
845
|
+
# Check for zip64 EOCD locator and zip64 EOCD record. Be
|
|
846
|
+
# extra careful here to not interpret any random data as
|
|
847
|
+
# zip64 data structures. If in doubt, silently continue
|
|
848
|
+
# reading the regular EOCD.
|
|
849
|
+
NOZIP64:
|
|
850
|
+
{
|
|
851
|
+
# Do not even start looking for any zip64 structures if
|
|
852
|
+
# that would not be supported.
|
|
853
|
+
if (! ZIP64_SUPPORTED) {
|
|
854
|
+
last NOZIP64;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
if ($eocdPosition < ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LENGTH + SIGNATURE_LENGTH) {
|
|
858
|
+
last NOZIP64;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
# Skip to before potential zip64 EOCD locator
|
|
862
|
+
$fh->seek(-(ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LENGTH) - SIGNATURE_LENGTH,
|
|
863
|
+
IO::Seekable::SEEK_CUR)
|
|
864
|
+
or return _ioError("seeking to before zip 64 EOCD locator");
|
|
865
|
+
my $zip64EOCDLocatorPosition =
|
|
866
|
+
$eocdPosition - ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LENGTH - SIGNATURE_LENGTH;
|
|
867
|
+
|
|
868
|
+
my $status;
|
|
869
|
+
my $bytesRead;
|
|
870
|
+
|
|
871
|
+
# Read potential zip64 EOCD locator signature
|
|
872
|
+
$status =
|
|
873
|
+
_readSignature($fh, $fileName,
|
|
874
|
+
ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE, 1);
|
|
875
|
+
return $status if $status == AZ_IO_ERROR;
|
|
876
|
+
if ($status == AZ_FORMAT_ERROR) {
|
|
877
|
+
$fh->seek($eocdPosition, IO::Seekable::SEEK_SET)
|
|
878
|
+
or return _ioError("seeking to EOCD");
|
|
879
|
+
last NOZIP64;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
# Read potential zip64 EOCD locator and verify it
|
|
883
|
+
my $locator = '';
|
|
884
|
+
$bytesRead = $fh->read($locator, ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LENGTH);
|
|
885
|
+
if ($bytesRead != ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_LENGTH) {
|
|
886
|
+
return _ioError("reading zip64 EOCD locator");
|
|
887
|
+
}
|
|
888
|
+
(undef, $zip64EOCDPosition, undef) =
|
|
889
|
+
unpack(ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_FORMAT, $locator);
|
|
890
|
+
if ($zip64EOCDPosition >
|
|
891
|
+
($zip64EOCDLocatorPosition - ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_LENGTH - SIGNATURE_LENGTH)) {
|
|
892
|
+
# No need to seek to EOCD since we're already there
|
|
893
|
+
last NOZIP64;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
# Skip to potential zip64 EOCD record
|
|
897
|
+
$fh->seek($zip64EOCDPosition, IO::Seekable::SEEK_SET)
|
|
898
|
+
or return _ioError("seeking to zip64 EOCD record");
|
|
899
|
+
|
|
900
|
+
# Read potential zip64 EOCD record signature
|
|
901
|
+
$status =
|
|
902
|
+
_readSignature($fh, $fileName,
|
|
903
|
+
ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_SIGNATURE, 1);
|
|
904
|
+
return $status if $status == AZ_IO_ERROR;
|
|
905
|
+
if ($status == AZ_FORMAT_ERROR) {
|
|
906
|
+
$fh->seek($eocdPosition, IO::Seekable::SEEK_SET)
|
|
907
|
+
or return _ioError("seeking to EOCD");
|
|
908
|
+
last NOZIP64;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
# Read potential zip64 EOCD record. Ignore the zip64
|
|
912
|
+
# extensible data sector.
|
|
913
|
+
my $record = '';
|
|
914
|
+
$bytesRead = $fh->read($record, ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_LENGTH);
|
|
915
|
+
if ($bytesRead != ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_LENGTH) {
|
|
916
|
+
return _ioError("reading zip64 EOCD record");
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
# Perform one final check, hoping that all implementors
|
|
920
|
+
# follow the recommendation of the specification
|
|
921
|
+
# regarding the size of the zip64 EOCD record
|
|
922
|
+
my ($zip64EODCRecordSize) = unpack("Q<", $record);
|
|
923
|
+
if ($zip64EOCDPosition + 12 + $zip64EODCRecordSize != $zip64EOCDLocatorPosition) {
|
|
924
|
+
$fh->seek($eocdPosition, IO::Seekable::SEEK_SET)
|
|
925
|
+
or return _ioError("seeking to EOCD");
|
|
926
|
+
last NOZIP64;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
$self->{'zip64'} = 1;
|
|
930
|
+
(
|
|
931
|
+
undef,
|
|
932
|
+
$self->{'versionMadeBy'},
|
|
933
|
+
$self->{'versionNeededToExtract'},
|
|
934
|
+
$self->{'diskNumber'},
|
|
935
|
+
$self->{'diskNumberWithStartOfCentralDirectory'},
|
|
936
|
+
$self->{'numberOfCentralDirectoriesOnThisDisk'},
|
|
937
|
+
$self->{'numberOfCentralDirectories'},
|
|
938
|
+
$self->{'centralDirectorySize'},
|
|
939
|
+
$self->{'centralDirectoryOffsetWRTStartingDiskNumber'}
|
|
940
|
+
) = unpack(ZIP64_END_OF_CENTRAL_DIRECTORY_RECORD_FORMAT, $record);
|
|
941
|
+
|
|
942
|
+
# Don't just happily bail out, we still need to read the
|
|
943
|
+
# zip file comment!
|
|
944
|
+
$fh->seek($eocdPosition, IO::Seekable::SEEK_SET)
|
|
945
|
+
or return _ioError("seeking to EOCD");
|
|
946
|
+
}
|
|
642
947
|
|
|
643
948
|
# Skip past signature
|
|
644
949
|
$fh->seek(SIGNATURE_LENGTH, IO::Seekable::SEEK_CUR)
|
|
645
|
-
or return _ioError("
|
|
950
|
+
or return _ioError("seeking past EOCD signature");
|
|
646
951
|
|
|
647
952
|
my $header = '';
|
|
648
953
|
my $bytesRead = $fh->read($header, END_OF_CENTRAL_DIRECTORY_LENGTH);
|
|
@@ -651,25 +956,43 @@ sub _readEndOfCentralDirectory {
|
|
|
651
956
|
}
|
|
652
957
|
|
|
653
958
|
my $zipfileCommentLength;
|
|
654
|
-
(
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
959
|
+
if (! $self->{'zip64'}) {
|
|
960
|
+
(
|
|
961
|
+
$self->{'diskNumber'},
|
|
962
|
+
$self->{'diskNumberWithStartOfCentralDirectory'},
|
|
963
|
+
$self->{'numberOfCentralDirectoriesOnThisDisk'},
|
|
964
|
+
$self->{'numberOfCentralDirectories'},
|
|
965
|
+
$self->{'centralDirectorySize'},
|
|
966
|
+
$self->{'centralDirectoryOffsetWRTStartingDiskNumber'},
|
|
967
|
+
$zipfileCommentLength
|
|
968
|
+
) = unpack(END_OF_CENTRAL_DIRECTORY_FORMAT, $header);
|
|
969
|
+
|
|
970
|
+
if ( $self->{'diskNumber'} == 0xffff
|
|
971
|
+
|| $self->{'diskNumberWithStartOfCentralDirectory'} == 0xffff
|
|
972
|
+
|| $self->{'numberOfCentralDirectoriesOnThisDisk'} == 0xffff
|
|
973
|
+
|| $self->{'numberOfCentralDirectories'} == 0xffff
|
|
974
|
+
|| $self->{'centralDirectorySize'} == 0xffffffff
|
|
975
|
+
|| $self->{'centralDirectoryOffsetWRTStartingDiskNumber'} == 0xffffffff) {
|
|
976
|
+
if (ZIP64_SUPPORTED) {
|
|
977
|
+
return _formatError("unexpected zip64 marker values in EOCD");
|
|
978
|
+
}
|
|
979
|
+
else {
|
|
980
|
+
return _zip64NotSupported();
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
else {
|
|
985
|
+
(
|
|
986
|
+
undef,
|
|
987
|
+
undef,
|
|
988
|
+
undef,
|
|
989
|
+
undef,
|
|
990
|
+
undef,
|
|
991
|
+
undef,
|
|
992
|
+
$zipfileCommentLength
|
|
993
|
+
) = unpack(END_OF_CENTRAL_DIRECTORY_FORMAT, $header);
|
|
671
994
|
}
|
|
672
|
-
|
|
995
|
+
|
|
673
996
|
if ($zipfileCommentLength) {
|
|
674
997
|
my $zipfileComment = '';
|
|
675
998
|
$bytesRead = $fh->read($zipfileComment, $zipfileCommentLength);
|
|
@@ -679,7 +1002,18 @@ use Data::Dumper;
|
|
|
679
1002
|
$self->{'zipfileComment'} = $zipfileComment;
|
|
680
1003
|
}
|
|
681
1004
|
|
|
682
|
-
|
|
1005
|
+
if (! $self->{'zip64'}) {
|
|
1006
|
+
return
|
|
1007
|
+
wantarray
|
|
1008
|
+
? (AZ_OK, $eocdPosition)
|
|
1009
|
+
: AZ_OK;
|
|
1010
|
+
}
|
|
1011
|
+
else {
|
|
1012
|
+
return
|
|
1013
|
+
wantarray
|
|
1014
|
+
? (AZ_OK, $zip64EOCDPosition)
|
|
1015
|
+
: AZ_OK;
|
|
1016
|
+
}
|
|
683
1017
|
}
|
|
684
1018
|
|
|
685
1019
|
# Seek in my file to the end, then read backwards until we find the
|