[PATCH] *-Compress-* 2.020
[p5sagit/p5-mst-13.2.git] / ext / IO-Compress / lib / IO / Uncompress / Unzip.pm
1 package IO::Uncompress::Unzip;
2
3 require 5.004 ;
4
5 # for RFC1952
6
7 use strict ;
8 use warnings;
9 use bytes;
10
11 use IO::Uncompress::RawInflate  2.020 ;
12 use IO::Compress::Base::Common  2.020 qw(:Status createSelfTiedObject);
13 use IO::Uncompress::Adapter::Inflate  2.020 ;
14 use IO::Uncompress::Adapter::Identity 2.020 ;
15 use IO::Compress::Zlib::Extra 2.020 ;
16 use IO::Compress::Zip::Constants 2.020 ;
17
18 use Compress::Raw::Zlib  2.020 qw(crc32) ;
19
20 BEGIN
21 {
22     eval { require IO::Uncompress::Adapter::Bunzip2 ;
23            import  IO::Uncompress::Adapter::Bunzip2 } ;
24    #eval { require IO::Uncompress::Adapter::UnLzma ;
25    #        import  IO::Uncompress::Adapter::UnLzma } ;
26 }
27
28
29 require Exporter ;
30
31 our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError, %headerLookup);
32
33 $VERSION = '2.020';
34 $UnzipError = '';
35
36 @ISA    = qw(Exporter IO::Uncompress::RawInflate);
37 @EXPORT_OK = qw( $UnzipError unzip );
38 %EXPORT_TAGS = %IO::Uncompress::RawInflate::EXPORT_TAGS ;
39 push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ;
40 Exporter::export_ok_tags('all');
41
42 %headerLookup = (
43         ZIP_CENTRAL_HDR_SIG,            \&skipCentralDirectory,
44         ZIP_END_CENTRAL_HDR_SIG,        \&skipEndCentralDirectory,
45         ZIP64_END_CENTRAL_REC_HDR_SIG,  \&skipCentralDirectory64Rec,
46         ZIP64_END_CENTRAL_LOC_HDR_SIG,  \&skipCentralDirectory64Loc,
47         ZIP64_ARCHIVE_EXTRA_SIG,        \&skipArchiveExtra,
48         ZIP64_DIGITAL_SIGNATURE_SIG,    \&skipDigitalSignature,
49         );
50
51 sub new
52 {
53     my $class = shift ;
54     my $obj = createSelfTiedObject($class, \$UnzipError);
55     $obj->_create(undef, 0, @_);
56 }
57
58 sub unzip
59 {
60     my $obj = createSelfTiedObject(undef, \$UnzipError);
61     return $obj->_inf(@_) ;
62 }
63
64 sub getExtraParams
65 {
66     use IO::Compress::Base::Common  2.020 qw(:Parse);
67
68     
69     return (
70 #            # Zip header fields
71             'Name'      => [1, 1, Parse_any,       undef],
72
73 #            'Streaming' => [1, 1, Parse_boolean,   1],
74         );    
75 }
76
77 sub ckParams
78 {
79     my $self = shift ;
80     my $got = shift ;
81
82     # unzip always needs crc32
83     $got->value('CRC32' => 1);
84
85     *$self->{UnzipData}{Name} = $got->value('Name');
86
87     return 1;
88 }
89
90 sub mkUncomp
91 {
92     my $self = shift ;
93     my $got = shift ;
94
95      my $magic = $self->ckMagic()
96         or return 0;
97
98     *$self->{Info} = $self->readHeader($magic)
99         or return undef ;
100
101     return 1;
102
103 }
104
105 sub ckMagic
106 {
107     my $self = shift;
108
109     my $magic ;
110     $self->smartReadExact(\$magic, 4);
111
112     *$self->{HeaderPending} = $magic ;
113
114     return $self->HeaderError("Minimum header size is " . 
115                               4 . " bytes") 
116         if length $magic != 4 ;                                    
117
118     return $self->HeaderError("Bad Magic")
119         if ! _isZipMagic($magic) ;
120
121     *$self->{Type} = 'zip';
122
123     return $magic ;
124 }
125
126
127
128 sub readHeader
129 {
130     my $self = shift;
131     my $magic = shift ;
132
133     my $name =  *$self->{UnzipData}{Name} ;
134     my $hdr = $self->_readZipHeader($magic) ;
135
136     while (defined $hdr)
137     {
138         if (! defined $name || $hdr->{Name} eq $name)
139         {
140             return $hdr ;
141         }
142
143         # skip the data
144         my $buffer;
145         if (*$self->{ZipData}{Streaming}) {
146
147             while (1) {
148
149                 my $b;
150                 my $status = $self->smartRead(\$b, 1024 * 16);
151                 return undef
152                     if $status <= 0 ;
153
154                 my $temp_buf;
155                 my $out;
156                 $status = *$self->{Uncomp}->uncompr(\$b, \$temp_buf, 0, $out);
157
158                 return $self->saveErrorString(undef, *$self->{Uncomp}{Error}, 
159                                                      *$self->{Uncomp}{ErrorNo})
160                     if $self->saveStatus($status) == STATUS_ERROR;                
161
162                 if ($status == STATUS_ENDSTREAM) {
163                     *$self->{Uncomp}->reset();
164                     $self->pushBack($b)  ;
165                     last;
166                 }
167             }
168
169             # skip the trailer
170             $self->smartReadExact(\$buffer, $hdr->{TrailerLength})
171                 or return $self->saveErrorString(undef, "Truncated file");
172         }
173         else {
174             my $c = $hdr->{CompressedLength}->get32bit();
175             $self->smartReadExact(\$buffer, $c)
176                 or return $self->saveErrorString(undef, "Truncated file");
177             $buffer = '';
178         }
179
180         $self->chkTrailer($buffer) == STATUS_OK
181             or return $self->saveErrorString(undef, "Truncated file");
182
183         $hdr = $self->_readFullZipHeader();
184
185         return $self->saveErrorString(undef, "Cannot find '$name'")
186             if $self->smartEof();
187     }
188
189     return undef;
190 }
191
192 sub chkTrailer
193 {
194     my $self = shift;
195     my $trailer = shift;
196
197     my ($sig, $CRC32, $cSize, $uSize) ;
198     my ($cSizeHi, $uSizeHi) = (0, 0);
199     if (*$self->{ZipData}{Streaming}) {
200         $sig   = unpack ("V", substr($trailer, 0, 4));
201         $CRC32 = unpack ("V", substr($trailer, 4, 4));
202
203         if (*$self->{ZipData}{Zip64} ) {
204             $cSize = U64::newUnpack_V64 substr($trailer,  8, 8);
205             $uSize = U64::newUnpack_V64 substr($trailer, 16, 8);
206         }
207         else {
208             $cSize = U64::newUnpack_V32 substr($trailer,  8, 4);
209             $uSize = U64::newUnpack_V32 substr($trailer, 12, 4);
210         }
211
212         return $self->TrailerError("Data Descriptor signature, got $sig")
213             if $sig != ZIP_DATA_HDR_SIG;
214     }
215     else {
216         ($CRC32, $cSize, $uSize) = 
217             (*$self->{ZipData}{Crc32},
218              *$self->{ZipData}{CompressedLen},
219              *$self->{ZipData}{UnCompressedLen});
220     }
221
222     if (*$self->{Strict}) {
223         return $self->TrailerError("CRC mismatch")
224             if $CRC32  != *$self->{ZipData}{CRC32} ;
225
226         return $self->TrailerError("CSIZE mismatch.")
227             if ! $cSize->equal(*$self->{CompSize});
228
229         return $self->TrailerError("USIZE mismatch.")
230             if ! $uSize->equal(*$self->{UnCompSize});
231     }
232
233     my $reachedEnd = STATUS_ERROR ;
234     # check for central directory or end of central directory
235     while (1)
236     {
237         my $magic ;
238         my $got = $self->smartRead(\$magic, 4);
239
240         return $self->saveErrorString(STATUS_ERROR, "Truncated file")
241             if $got != 4 && *$self->{Strict};
242
243         if ($got == 0) {
244             return STATUS_EOF ;
245         }
246         elsif ($got < 0) {
247             return STATUS_ERROR ;
248         }
249         elsif ($got < 4) {
250             $self->pushBack($magic)  ;
251             return STATUS_OK ;
252         }
253
254         my $sig = unpack("V", $magic) ;
255
256         my $hdr;
257         if ($hdr = $headerLookup{$sig})
258         {
259             if (&$hdr($self, $magic) != STATUS_OK ) {
260                 if (*$self->{Strict}) {
261                     return STATUS_ERROR ;
262                 }
263                 else {
264                     $self->clearError();
265                     return STATUS_OK ;
266                 }
267             }
268
269             if ($sig == ZIP_END_CENTRAL_HDR_SIG)
270             {
271                 return STATUS_OK ;
272                 last;
273             }
274         }
275         elsif ($sig == ZIP_LOCAL_HDR_SIG)
276         {
277             $self->pushBack($magic)  ;
278             return STATUS_OK ;
279         }
280         else
281         {
282             # put the data back
283             $self->pushBack($magic)  ;
284             last;
285         }
286     }
287
288     return $reachedEnd ;
289 }
290
291 sub skipCentralDirectory
292 {
293     my $self = shift;
294     my $magic = shift ;
295
296     my $buffer;
297     $self->smartReadExact(\$buffer, 46 - 4)
298         or return $self->TrailerError("Minimum header size is " . 
299                                      46 . " bytes") ;
300
301     my $keep = $magic . $buffer ;
302     *$self->{HeaderPending} = $keep ;
303
304    #my $versionMadeBy      = unpack ("v", substr($buffer, 4-4,  2));
305    #my $extractVersion     = unpack ("v", substr($buffer, 6-4,  2));
306    #my $gpFlag             = unpack ("v", substr($buffer, 8-4,  2));
307    #my $compressedMethod   = unpack ("v", substr($buffer, 10-4, 2));
308    #my $lastModTime        = unpack ("V", substr($buffer, 12-4, 4));
309    #my $crc32              = unpack ("V", substr($buffer, 16-4, 4));
310     my $compressedLength   = unpack ("V", substr($buffer, 20-4, 4));
311     my $uncompressedLength = unpack ("V", substr($buffer, 24-4, 4));
312     my $filename_length    = unpack ("v", substr($buffer, 28-4, 2)); 
313     my $extra_length       = unpack ("v", substr($buffer, 30-4, 2));
314     my $comment_length     = unpack ("v", substr($buffer, 32-4, 2));
315    #my $disk_start         = unpack ("v", substr($buffer, 34-4, 2));
316    #my $int_file_attrib    = unpack ("v", substr($buffer, 36-4, 2));
317    #my $ext_file_attrib    = unpack ("V", substr($buffer, 38-4, 2));
318    #my $lcl_hdr_offset     = unpack ("V", substr($buffer, 42-4, 2));
319
320     
321     my $filename;
322     my $extraField;
323     my $comment ;
324     if ($filename_length)
325     {
326         $self->smartReadExact(\$filename, $filename_length)
327             or return $self->TruncatedTrailer("filename");
328         $keep .= $filename ;
329     }
330
331     if ($extra_length)
332     {
333         $self->smartReadExact(\$extraField, $extra_length)
334             or return $self->TruncatedTrailer("extra");
335         $keep .= $extraField ;
336     }
337
338     if ($comment_length)
339     {
340         $self->smartReadExact(\$comment, $comment_length)
341             or return $self->TruncatedTrailer("comment");
342         $keep .= $comment ;
343     }
344
345     return STATUS_OK ;
346 }
347
348 sub skipArchiveExtra
349 {
350     my $self = shift;
351     my $magic = shift ;
352
353     my $buffer;
354     $self->smartReadExact(\$buffer, 4)
355         or return $self->TrailerError("Minimum header size is " . 
356                                      4 . " bytes") ;
357
358     my $keep = $magic . $buffer ;
359
360     my $size = unpack ("V", $buffer);
361
362     $self->smartReadExact(\$buffer, $size)
363         or return $self->TrailerError("Minimum header size is " . 
364                                      $size . " bytes") ;
365
366     $keep .= $buffer ;
367     *$self->{HeaderPending} = $keep ;
368
369     return STATUS_OK ;
370 }
371
372
373 sub skipCentralDirectory64Rec
374 {
375     my $self = shift;
376     my $magic = shift ;
377
378     my $buffer;
379     $self->smartReadExact(\$buffer, 8)
380         or return $self->TrailerError("Minimum header size is " . 
381                                      8 . " bytes") ;
382
383     my $keep = $magic . $buffer ;
384
385     my ($sizeLo, $sizeHi)  = unpack ("V V", $buffer);
386
387     # TODO - take SizeHi into account
388     $self->smartReadExact(\$buffer, $sizeLo)
389         or return $self->TrailerError("Minimum header size is " . 
390                                      $sizeLo . " bytes") ;
391
392     $keep .= $buffer ;
393     *$self->{HeaderPending} = $keep ;
394
395    #my $versionMadeBy      = unpack ("v",   substr($buffer,  0, 2));
396    #my $extractVersion     = unpack ("v",   substr($buffer,  2, 2));
397    #my $diskNumber         = unpack ("V",   substr($buffer,  4, 4));
398    #my $cntrlDirDiskNo     = unpack ("V",   substr($buffer,  8, 4));
399    #my $entriesInThisCD    = unpack ("V V", substr($buffer, 12, 8));
400    #my $entriesInCD        = unpack ("V V", substr($buffer, 20, 8));
401    #my $sizeOfCD           = unpack ("V V", substr($buffer, 28, 8));
402    #my $offsetToCD         = unpack ("V V", substr($buffer, 36, 8));
403
404     return STATUS_OK ;
405 }
406
407 sub skipCentralDirectory64Loc
408 {
409     my $self = shift;
410     my $magic = shift ;
411
412     my $buffer;
413     $self->smartReadExact(\$buffer, 20 - 4)
414         or return $self->TrailerError("Minimum header size is " . 
415                                      20 . " bytes") ;
416
417     my $keep = $magic . $buffer ;
418     *$self->{HeaderPending} = $keep ;
419
420    #my $startCdDisk        = unpack ("V",   substr($buffer,  4-4, 4));
421    #my $offsetToCD         = unpack ("V V", substr($buffer,  8-4, 8));
422    #my $diskCount          = unpack ("V",   substr($buffer, 16-4, 4));
423
424     return STATUS_OK ;
425 }
426
427 sub skipEndCentralDirectory
428 {
429     my $self = shift;
430     my $magic = shift ;
431
432     my $buffer;
433     $self->smartReadExact(\$buffer, 22 - 4)
434         or return $self->TrailerError("Minimum header size is " . 
435                                      22 . " bytes") ;
436
437     my $keep = $magic . $buffer ;
438     *$self->{HeaderPending} = $keep ;
439
440    #my $diskNumber         = unpack ("v", substr($buffer, 4-4,  2));
441    #my $cntrlDirDiskNo     = unpack ("v", substr($buffer, 6-4,  2));
442    #my $entriesInThisCD    = unpack ("v", substr($buffer, 8-4,  2));
443    #my $entriesInCD        = unpack ("v", substr($buffer, 10-4, 2));
444    #my $sizeOfCD           = unpack ("V", substr($buffer, 12-4, 2));
445    #my $offsetToCD         = unpack ("V", substr($buffer, 16-4, 2));
446     my $comment_length     = unpack ("v", substr($buffer, 20-4, 2));
447
448     
449     my $comment ;
450     if ($comment_length)
451     {
452         $self->smartReadExact(\$comment, $comment_length)
453             or return $self->TruncatedTrailer("comment");
454         $keep .= $comment ;
455     }
456
457     return STATUS_OK ;
458 }
459
460
461 sub _isZipMagic
462 {
463     my $buffer = shift ;
464     return 0 if length $buffer < 4 ;
465     my $sig = unpack("V", $buffer) ;
466     return $sig == ZIP_LOCAL_HDR_SIG ;
467 }
468
469
470 sub _readFullZipHeader($)
471 {
472     my ($self) = @_ ;
473     my $magic = '' ;
474
475     $self->smartReadExact(\$magic, 4);
476
477     *$self->{HeaderPending} = $magic ;
478
479     return $self->HeaderError("Minimum header size is " . 
480                               30 . " bytes") 
481         if length $magic != 4 ;                                    
482
483
484     return $self->HeaderError("Bad Magic")
485         if ! _isZipMagic($magic) ;
486
487     my $status = $self->_readZipHeader($magic);
488     delete *$self->{Transparent} if ! defined $status ;
489     return $status ;
490 }
491
492 sub _readZipHeader($)
493 {
494     my ($self, $magic) = @_ ;
495     my ($HeaderCRC) ;
496     my ($buffer) = '' ;
497
498     $self->smartReadExact(\$buffer, 30 - 4)
499         or return $self->HeaderError("Minimum header size is " . 
500                                      30 . " bytes") ;
501
502     my $keep = $magic . $buffer ;
503     *$self->{HeaderPending} = $keep ;
504
505     my $extractVersion     = unpack ("v", substr($buffer, 4-4,  2));
506     my $gpFlag             = unpack ("v", substr($buffer, 6-4,  2));
507     my $compressedMethod   = unpack ("v", substr($buffer, 8-4,  2));
508     my $lastModTime        = unpack ("V", substr($buffer, 10-4, 4));
509     my $crc32              = unpack ("V", substr($buffer, 14-4, 4));
510     my $compressedLength   = new U64 unpack ("V", substr($buffer, 18-4, 4));
511     my $uncompressedLength = new U64 unpack ("V", substr($buffer, 22-4, 4));
512     my $filename_length    = unpack ("v", substr($buffer, 26-4, 2)); 
513     my $extra_length       = unpack ("v", substr($buffer, 28-4, 2));
514
515     my $filename;
516     my $extraField;
517     my @EXTRA = ();
518     my $streamingMode = ($gpFlag & ZIP_GP_FLAG_STREAMING_MASK) ? 1 : 0 ;
519
520     return $self->HeaderError("Streamed Stored content not supported")
521         if $streamingMode && $compressedMethod == 0 ;
522
523     return $self->HeaderError("Encrypted content not supported")
524         if $gpFlag & (ZIP_GP_FLAG_ENCRYPTED_MASK|ZIP_GP_FLAG_STRONG_ENCRYPTED_MASK);
525
526     return $self->HeaderError("Patch content not supported")
527         if $gpFlag & ZIP_GP_FLAG_PATCHED_MASK;
528
529     *$self->{ZipData}{Streaming} = $streamingMode;
530
531
532     if ($filename_length)
533     {
534         $self->smartReadExact(\$filename, $filename_length)
535             or return $self->TruncatedHeader("Filename");
536         $keep .= $filename ;
537     }
538
539     my $zip64 = 0 ;
540
541     if ($extra_length)
542     {
543         $self->smartReadExact(\$extraField, $extra_length)
544             or return $self->TruncatedHeader("Extra Field");
545
546         my $bad = IO::Compress::Zlib::Extra::parseRawExtra($extraField,
547                                                 \@EXTRA, 1, 0);
548         return $self->HeaderError($bad)
549             if defined $bad;
550
551         $keep .= $extraField ;
552
553         my %Extra ;
554         for (@EXTRA)
555         {
556             $Extra{$_->[0]} = \$_->[1];
557         }
558         
559         if (defined $Extra{ZIP_EXTRA_ID_ZIP64()})
560         {
561             $zip64 = 1 ;
562
563             my $buff = ${ $Extra{ZIP_EXTRA_ID_ZIP64()} };
564
565             # TODO - This code assumes that all the fields in the Zip64
566             # extra field aren't necessarily present. The spec says that
567             # they only exist if the equivalent local headers are -1.
568             # Need to check that info-zip fills out -1 in the local header
569             # correctly.
570
571             if (! $streamingMode) {
572                 my $offset = 0 ;
573
574                 $uncompressedLength = U64::newUnpack_V64 substr($buff,  0, 8)
575                     if $uncompressedLength == 0xFFFF ;
576
577                 $offset += 8 ;
578
579                 $compressedLength = U64::newUnpack_V64 substr($buff, $offset, 8)
580                     if $compressedLength == 0xFFFF ;
581
582                 $offset += 8 ;
583
584                 #my $cheaderOffset = U64::newUnpack_V64 substr($buff, 16, 8);
585                 #my $diskNumber = unpack ("V", substr($buff, 24, 4));
586            }
587         }
588     }
589
590     *$self->{ZipData}{Zip64} = $zip64;
591
592     if (! $streamingMode) {
593         *$self->{ZipData}{Streaming} = 0;
594         *$self->{ZipData}{Crc32} = $crc32;
595         *$self->{ZipData}{CompressedLen} = $compressedLength;
596         *$self->{ZipData}{UnCompressedLen} = $uncompressedLength;
597         *$self->{CompressedInputLengthRemaining} =
598             *$self->{CompressedInputLength} = $compressedLength->get32bit();
599     }
600
601     *$self->{ZipData}{Method} = $compressedMethod;
602     if ($compressedMethod == ZIP_CM_DEFLATE)
603     {
604         *$self->{Type} = 'zip-deflate';
605         my $obj = IO::Uncompress::Adapter::Inflate::mkUncompObject(1,0,0);
606
607         *$self->{Uncomp} = $obj;
608         *$self->{ZipData}{CRC32} = crc32(undef);
609     }
610     elsif ($compressedMethod == ZIP_CM_BZIP2)
611     {
612         return $self->HeaderError("Unsupported Compression format $compressedMethod")
613             if ! defined $IO::Uncompress::Adapter::Bunzip2::VERSION ;
614         
615         *$self->{Type} = 'zip-bzip2';
616         
617         my $obj = IO::Uncompress::Adapter::Bunzip2::mkUncompObject();
618
619         *$self->{Uncomp} = $obj;
620         *$self->{ZipData}{CRC32} = crc32(undef);
621     }
622 #    elsif ($compressedMethod == ZIP_CM_LZMA)
623 #    {
624 #        return $self->HeaderError("Unsupported Compression format $compressedMethod")
625 #            if ! defined $IO::Uncompress::Adapter::UnLzma::VERSION ;
626 #        
627 #        *$self->{Type} = 'zip-lzma';
628 #        
629 #        my $obj = IO::Uncompress::Adapter::UnLzma::mkUncompObject();
630 #
631 #        *$self->{Uncomp} = $obj;
632 #        *$self->{ZipData}{CRC32} = crc32(undef);
633 #    }
634     elsif ($compressedMethod == ZIP_CM_STORE)
635     {
636         # TODO -- add support for reading uncompressed
637
638         *$self->{Type} = 'zip-stored';
639         
640         my $obj = IO::Uncompress::Adapter::Identity::mkUncompObject();
641
642         *$self->{Uncomp} = $obj;
643     }
644     else
645     {
646         return $self->HeaderError("Unsupported Compression format $compressedMethod");
647     }
648
649     return {
650         'Type'               => 'zip',
651         'FingerprintLength'  => 4,
652         #'HeaderLength'       => $compressedMethod == 8 ? length $keep : 0,
653         'HeaderLength'       => length $keep,
654         'Zip64'              => $zip64,
655         'TrailerLength'      => ! $streamingMode ? 0 : $zip64 ? 24 : 16,
656         'Header'             => $keep,
657         'CompressedLength'   => $compressedLength ,
658         'UncompressedLength' => $uncompressedLength ,
659         'CRC32'              => $crc32 ,
660         'Name'               => $filename,
661         'Time'               => _dosToUnixTime($lastModTime),
662         'Stream'             => $streamingMode,
663
664         'MethodID'           => $compressedMethod,
665         'MethodName'         => $compressedMethod == ZIP_CM_DEFLATE 
666                                  ? "Deflated" 
667                                  : $compressedMethod == ZIP_CM_BZIP2
668                                      ? "Bzip2"
669                                      : $compressedMethod == ZIP_CM_STORE
670                                          ? "Stored"
671                                          : "Unknown" ,
672
673 #        'TextFlag'      => $flag & GZIP_FLG_FTEXT ? 1 : 0,
674 #        'HeaderCRCFlag' => $flag & GZIP_FLG_FHCRC ? 1 : 0,
675 #        'NameFlag'      => $flag & GZIP_FLG_FNAME ? 1 : 0,
676 #        'CommentFlag'   => $flag & GZIP_FLG_FCOMMENT ? 1 : 0,
677 #        'ExtraFlag'     => $flag & GZIP_FLG_FEXTRA ? 1 : 0,
678 #        'Comment'       => $comment,
679 #        'OsID'          => $os,
680 #        'OsName'        => defined $GZIP_OS_Names{$os} 
681 #                                 ? $GZIP_OS_Names{$os} : "Unknown",
682 #        'HeaderCRC'     => $HeaderCRC,
683 #        'Flags'         => $flag,
684 #        'ExtraFlags'    => $xfl,
685         'ExtraFieldRaw' => $extraField,
686         'ExtraField'    => [ @EXTRA ],
687
688
689       }
690 }
691
692 sub filterUncompressed
693 {
694     my $self = shift ;
695
696     if (*$self->{ZipData}{Method} == 12) {
697         *$self->{ZipData}{CRC32} = crc32(${$_[0]}, *$self->{ZipData}{CRC32});
698     }
699     else {
700         *$self->{ZipData}{CRC32} = *$self->{Uncomp}->crc32() ;
701     }
702 }    
703
704
705 # from Archive::Zip & info-zip
706 sub _dosToUnixTime
707 {
708         my $dt = shift;
709
710         my $year = ( ( $dt >> 25 ) & 0x7f ) + 80;
711         my $mon  = ( ( $dt >> 21 ) & 0x0f ) - 1;
712         my $mday = ( ( $dt >> 16 ) & 0x1f );
713
714         my $hour = ( ( $dt >> 11 ) & 0x1f );
715         my $min  = ( ( $dt >> 5 ) & 0x3f );
716         my $sec  = ( ( $dt << 1 ) & 0x3e );
717
718
719     use POSIX 'mktime';
720
721     my $time_t = mktime( $sec, $min, $hour, $mday, $mon, $year, 0, 0, -1 );
722     return 0 if ! defined $time_t;
723         return $time_t;
724 }
725
726
727 1;
728
729 __END__
730
731
732 =head1 NAME
733
734 IO::Uncompress::Unzip - Read zip files/buffers
735
736 =head1 SYNOPSIS
737
738     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
739
740     my $status = unzip $input => $output [,OPTS]
741         or die "unzip failed: $UnzipError\n";
742
743     my $z = new IO::Uncompress::Unzip $input [OPTS] 
744         or die "unzip failed: $UnzipError\n";
745
746     $status = $z->read($buffer)
747     $status = $z->read($buffer, $length)
748     $status = $z->read($buffer, $length, $offset)
749     $line = $z->getline()
750     $char = $z->getc()
751     $char = $z->ungetc()
752     $char = $z->opened()
753
754     $status = $z->inflateSync()
755
756     $data = $z->trailingData()
757     $status = $z->nextStream()
758     $data = $z->getHeaderInfo()
759     $z->tell()
760     $z->seek($position, $whence)
761     $z->binmode()
762     $z->fileno()
763     $z->eof()
764     $z->close()
765
766     $UnzipError ;
767
768     # IO::File mode
769
770     <$z>
771     read($z, $buffer);
772     read($z, $buffer, $length);
773     read($z, $buffer, $length, $offset);
774     tell($z)
775     seek($z, $position, $whence)
776     binmode($z)
777     fileno($z)
778     eof($z)
779     close($z)
780
781 =head1 DESCRIPTION
782
783 This module provides a Perl interface that allows the reading of
784 zlib files/buffers.
785
786 For writing zip files/buffers, see the companion module IO::Compress::Zip.
787
788 =head1 Functional Interface
789
790 A top-level function, C<unzip>, is provided to carry out
791 "one-shot" uncompression between buffers and/or files. For finer
792 control over the uncompression process, see the L</"OO Interface">
793 section.
794
795     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
796
797     unzip $input => $output [,OPTS] 
798         or die "unzip failed: $UnzipError\n";
799
800 The functional interface needs Perl5.005 or better.
801
802 =head2 unzip $input => $output [, OPTS]
803
804 C<unzip> expects at least two parameters, C<$input> and C<$output>.
805
806 =head3 The C<$input> parameter
807
808 The parameter, C<$input>, is used to define the source of
809 the compressed data. 
810
811 It can take one of the following forms:
812
813 =over 5
814
815 =item A filename
816
817 If the C<$input> parameter is a simple scalar, it is assumed to be a
818 filename. This file will be opened for reading and the input data
819 will be read from it.
820
821 =item A filehandle
822
823 If the C<$input> parameter is a filehandle, the input data will be
824 read from it.
825 The string '-' can be used as an alias for standard input.
826
827 =item A scalar reference 
828
829 If C<$input> is a scalar reference, the input data will be read
830 from C<$$input>.
831
832 =item An array reference 
833
834 If C<$input> is an array reference, each element in the array must be a
835 filename.
836
837 The input data will be read from each file in turn. 
838
839 The complete array will be walked to ensure that it only
840 contains valid filenames before any data is uncompressed.
841
842 =item An Input FileGlob string
843
844 If C<$input> is a string that is delimited by the characters "<" and ">"
845 C<unzip> will assume that it is an I<input fileglob string>. The
846 input is the list of files that match the fileglob.
847
848 If the fileglob does not match any files ...
849
850 See L<File::GlobMapper|File::GlobMapper> for more details.
851
852 =back
853
854 If the C<$input> parameter is any other type, C<undef> will be returned.
855
856 =head3 The C<$output> parameter
857
858 The parameter C<$output> is used to control the destination of the
859 uncompressed data. This parameter can take one of these forms.
860
861 =over 5
862
863 =item A filename
864
865 If the C<$output> parameter is a simple scalar, it is assumed to be a
866 filename.  This file will be opened for writing and the uncompressed
867 data will be written to it.
868
869 =item A filehandle
870
871 If the C<$output> parameter is a filehandle, the uncompressed data
872 will be written to it.
873 The string '-' can be used as an alias for standard output.
874
875 =item A scalar reference 
876
877 If C<$output> is a scalar reference, the uncompressed data will be
878 stored in C<$$output>.
879
880 =item An Array Reference
881
882 If C<$output> is an array reference, the uncompressed data will be
883 pushed onto the array.
884
885 =item An Output FileGlob
886
887 If C<$output> is a string that is delimited by the characters "<" and ">"
888 C<unzip> will assume that it is an I<output fileglob string>. The
889 output is the list of files that match the fileglob.
890
891 When C<$output> is an fileglob string, C<$input> must also be a fileglob
892 string. Anything else is an error.
893
894 =back
895
896 If the C<$output> parameter is any other type, C<undef> will be returned.
897
898 =head2 Notes
899
900 When C<$input> maps to multiple compressed files/buffers and C<$output> is
901 a single file/buffer, after uncompression C<$output> will contain a
902 concatenation of all the uncompressed data from each of the input
903 files/buffers.
904
905 =head2 Optional Parameters
906
907 Unless specified below, the optional parameters for C<unzip>,
908 C<OPTS>, are the same as those used with the OO interface defined in the
909 L</"Constructor Options"> section below.
910
911 =over 5
912
913 =item C<< AutoClose => 0|1 >>
914
915 This option applies to any input or output data streams to 
916 C<unzip> that are filehandles.
917
918 If C<AutoClose> is specified, and the value is true, it will result in all
919 input and/or output filehandles being closed once C<unzip> has
920 completed.
921
922 This parameter defaults to 0.
923
924 =item C<< BinModeOut => 0|1 >>
925
926 When writing to a file or filehandle, set C<binmode> before writing to the
927 file.
928
929 Defaults to 0.
930
931 =item C<< Append => 0|1 >>
932
933 TODO
934
935 =item C<< MultiStream => 0|1 >>
936
937 If the input file/buffer contains multiple compressed data streams, this
938 option will uncompress the whole lot as a single data stream.
939
940 Defaults to 0.
941
942 =item C<< TrailingData => $scalar >>
943
944 Returns the data, if any, that is present immediately after the compressed
945 data stream once uncompression is complete. 
946
947 This option can be used when there is useful information immediately
948 following the compressed data stream, and you don't know the length of the
949 compressed data stream.
950
951 If the input is a buffer, C<trailingData> will return everything from the
952 end of the compressed data stream to the end of the buffer.
953
954 If the input is a filehandle, C<trailingData> will return the data that is
955 left in the filehandle input buffer once the end of the compressed data
956 stream has been reached. You can then use the filehandle to read the rest
957 of the input file. 
958
959 Don't bother using C<trailingData> if the input is a filename.
960
961 If you know the length of the compressed data stream before you start
962 uncompressing, you can avoid having to use C<trailingData> by setting the
963 C<InputLength> option.
964
965 =back
966
967 =head2 Examples
968
969 To read the contents of the file C<file1.txt.zip> and write the
970 compressed data to the file C<file1.txt>.
971
972     use strict ;
973     use warnings ;
974     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
975
976     my $input = "file1.txt.zip";
977     my $output = "file1.txt";
978     unzip $input => $output
979         or die "unzip failed: $UnzipError\n";
980
981 To read from an existing Perl filehandle, C<$input>, and write the
982 uncompressed data to a buffer, C<$buffer>.
983
984     use strict ;
985     use warnings ;
986     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
987     use IO::File ;
988
989     my $input = new IO::File "<file1.txt.zip"
990         or die "Cannot open 'file1.txt.zip': $!\n" ;
991     my $buffer ;
992     unzip $input => \$buffer 
993         or die "unzip failed: $UnzipError\n";
994
995 To uncompress all files in the directory "/my/home" that match "*.txt.zip" and store the compressed data in the same directory
996
997     use strict ;
998     use warnings ;
999     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1000
1001     unzip '</my/home/*.txt.zip>' => '</my/home/#1.txt>'
1002         or die "unzip failed: $UnzipError\n";
1003
1004 and if you want to compress each file one at a time, this will do the trick
1005
1006     use strict ;
1007     use warnings ;
1008     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1009
1010     for my $input ( glob "/my/home/*.txt.zip" )
1011     {
1012         my $output = $input;
1013         $output =~ s/.zip// ;
1014         unzip $input => $output 
1015             or die "Error compressing '$input': $UnzipError\n";
1016     }
1017
1018 =head1 OO Interface
1019
1020 =head2 Constructor
1021
1022 The format of the constructor for IO::Uncompress::Unzip is shown below
1023
1024     my $z = new IO::Uncompress::Unzip $input [OPTS]
1025         or die "IO::Uncompress::Unzip failed: $UnzipError\n";
1026
1027 Returns an C<IO::Uncompress::Unzip> object on success and undef on failure.
1028 The variable C<$UnzipError> will contain an error message on failure.
1029
1030 If you are running Perl 5.005 or better the object, C<$z>, returned from
1031 IO::Uncompress::Unzip can be used exactly like an L<IO::File|IO::File> filehandle.
1032 This means that all normal input file operations can be carried out with
1033 C<$z>.  For example, to read a line from a compressed file/buffer you can
1034 use either of these forms
1035
1036     $line = $z->getline();
1037     $line = <$z>;
1038
1039 The mandatory parameter C<$input> is used to determine the source of the
1040 compressed data. This parameter can take one of three forms.
1041
1042 =over 5
1043
1044 =item A filename
1045
1046 If the C<$input> parameter is a scalar, it is assumed to be a filename. This
1047 file will be opened for reading and the compressed data will be read from it.
1048
1049 =item A filehandle
1050
1051 If the C<$input> parameter is a filehandle, the compressed data will be
1052 read from it.
1053 The string '-' can be used as an alias for standard input.
1054
1055 =item A scalar reference 
1056
1057 If C<$input> is a scalar reference, the compressed data will be read from
1058 C<$$output>.
1059
1060 =back
1061
1062 =head2 Constructor Options
1063
1064 The option names defined below are case insensitive and can be optionally
1065 prefixed by a '-'.  So all of the following are valid
1066
1067     -AutoClose
1068     -autoclose
1069     AUTOCLOSE
1070     autoclose
1071
1072 OPTS is a combination of the following options:
1073
1074 =over 5
1075
1076 =item C<< AutoClose => 0|1 >>
1077
1078 This option is only valid when the C<$input> parameter is a filehandle. If
1079 specified, and the value is true, it will result in the file being closed once
1080 either the C<close> method is called or the IO::Uncompress::Unzip object is
1081 destroyed.
1082
1083 This parameter defaults to 0.
1084
1085 =item C<< MultiStream => 0|1 >>
1086
1087 Treats the complete zip file/buffer as a single compressed data
1088 stream. When reading in multi-stream mode each member of the zip
1089 file/buffer will be uncompressed in turn until the end of the file/buffer
1090 is encountered.
1091
1092 This parameter defaults to 0.
1093
1094 =item C<< Prime => $string >>
1095
1096 This option will uncompress the contents of C<$string> before processing the
1097 input file/buffer.
1098
1099 This option can be useful when the compressed data is embedded in another
1100 file/data structure and it is not possible to work out where the compressed
1101 data begins without having to read the first few bytes. If this is the
1102 case, the uncompression can be I<primed> with these bytes using this
1103 option.
1104
1105 =item C<< Transparent => 0|1 >>
1106
1107 If this option is set and the input file/buffer is not compressed data,
1108 the module will allow reading of it anyway.
1109
1110 In addition, if the input file/buffer does contain compressed data and
1111 there is non-compressed data immediately following it, setting this option
1112 will make this module treat the whole file/bufffer as a single data stream.
1113
1114 This option defaults to 1.
1115
1116 =item C<< BlockSize => $num >>
1117
1118 When reading the compressed input data, IO::Uncompress::Unzip will read it in
1119 blocks of C<$num> bytes.
1120
1121 This option defaults to 4096.
1122
1123 =item C<< InputLength => $size >>
1124
1125 When present this option will limit the number of compressed bytes read
1126 from the input file/buffer to C<$size>. This option can be used in the
1127 situation where there is useful data directly after the compressed data
1128 stream and you know beforehand the exact length of the compressed data
1129 stream. 
1130
1131 This option is mostly used when reading from a filehandle, in which case
1132 the file pointer will be left pointing to the first byte directly after the
1133 compressed data stream.
1134
1135 This option defaults to off.
1136
1137 =item C<< Append => 0|1 >>
1138
1139 This option controls what the C<read> method does with uncompressed data.
1140
1141 If set to 1, all uncompressed data will be appended to the output parameter
1142 of the C<read> method.
1143
1144 If set to 0, the contents of the output parameter of the C<read> method
1145 will be overwritten by the uncompressed data.
1146
1147 Defaults to 0.
1148
1149 =item C<< Strict => 0|1 >>
1150
1151 This option controls whether the extra checks defined below are used when
1152 carrying out the decompression. When Strict is on, the extra tests are
1153 carried out, when Strict is off they are not.
1154
1155 The default for this option is off.
1156
1157 =back
1158
1159 =head2 Examples
1160
1161 TODO
1162
1163 =head1 Methods 
1164
1165 =head2 read
1166
1167 Usage is
1168
1169     $status = $z->read($buffer)
1170
1171 Reads a block of compressed data (the size the the compressed block is
1172 determined by the C<Buffer> option in the constructor), uncompresses it and
1173 writes any uncompressed data into C<$buffer>. If the C<Append> parameter is
1174 set in the constructor, the uncompressed data will be appended to the
1175 C<$buffer> parameter. Otherwise C<$buffer> will be overwritten.
1176
1177 Returns the number of uncompressed bytes written to C<$buffer>, zero if eof
1178 or a negative number on error.
1179
1180 =head2 read
1181
1182 Usage is
1183
1184     $status = $z->read($buffer, $length)
1185     $status = $z->read($buffer, $length, $offset)
1186
1187     $status = read($z, $buffer, $length)
1188     $status = read($z, $buffer, $length, $offset)
1189
1190 Attempt to read C<$length> bytes of uncompressed data into C<$buffer>.
1191
1192 The main difference between this form of the C<read> method and the
1193 previous one, is that this one will attempt to return I<exactly> C<$length>
1194 bytes. The only circumstances that this function will not is if end-of-file
1195 or an IO error is encountered.
1196
1197 Returns the number of uncompressed bytes written to C<$buffer>, zero if eof
1198 or a negative number on error.
1199
1200 =head2 getline
1201
1202 Usage is
1203
1204     $line = $z->getline()
1205     $line = <$z>
1206
1207 Reads a single line. 
1208
1209 This method fully supports the use of of the variable C<$/> (or
1210 C<$INPUT_RECORD_SEPARATOR> or C<$RS> when C<English> is in use) to
1211 determine what constitutes an end of line. Paragraph mode, record mode and
1212 file slurp mode are all supported. 
1213
1214 =head2 getc
1215
1216 Usage is 
1217
1218     $char = $z->getc()
1219
1220 Read a single character.
1221
1222 =head2 ungetc
1223
1224 Usage is
1225
1226     $char = $z->ungetc($string)
1227
1228 =head2 inflateSync
1229
1230 Usage is
1231
1232     $status = $z->inflateSync()
1233
1234 TODO
1235
1236 =head2 getHeaderInfo
1237
1238 Usage is
1239
1240     $hdr  = $z->getHeaderInfo();
1241     @hdrs = $z->getHeaderInfo();
1242
1243 This method returns either a hash reference (in scalar context) or a list
1244 or hash references (in array context) that contains information about each
1245 of the header fields in the compressed data stream(s).
1246
1247 =head2 tell
1248
1249 Usage is
1250
1251     $z->tell()
1252     tell $z
1253
1254 Returns the uncompressed file offset.
1255
1256 =head2 eof
1257
1258 Usage is
1259
1260     $z->eof();
1261     eof($z);
1262
1263 Returns true if the end of the compressed input stream has been reached.
1264
1265 =head2 seek
1266
1267     $z->seek($position, $whence);
1268     seek($z, $position, $whence);
1269
1270 Provides a sub-set of the C<seek> functionality, with the restriction
1271 that it is only legal to seek forward in the input file/buffer.
1272 It is a fatal error to attempt to seek backward.
1273
1274 The C<$whence> parameter takes one the usual values, namely SEEK_SET,
1275 SEEK_CUR or SEEK_END.
1276
1277 Returns 1 on success, 0 on failure.
1278
1279 =head2 binmode
1280
1281 Usage is
1282
1283     $z->binmode
1284     binmode $z ;
1285
1286 This is a noop provided for completeness.
1287
1288 =head2 opened
1289
1290     $z->opened()
1291
1292 Returns true if the object currently refers to a opened file/buffer. 
1293
1294 =head2 autoflush
1295
1296     my $prev = $z->autoflush()
1297     my $prev = $z->autoflush(EXPR)
1298
1299 If the C<$z> object is associated with a file or a filehandle, this method
1300 returns the current autoflush setting for the underlying filehandle. If
1301 C<EXPR> is present, and is non-zero, it will enable flushing after every
1302 write/print operation.
1303
1304 If C<$z> is associated with a buffer, this method has no effect and always
1305 returns C<undef>.
1306
1307 B<Note> that the special variable C<$|> B<cannot> be used to set or
1308 retrieve the autoflush setting.
1309
1310 =head2 input_line_number
1311
1312     $z->input_line_number()
1313     $z->input_line_number(EXPR)
1314
1315 Returns the current uncompressed line number. If C<EXPR> is present it has
1316 the effect of setting the line number. Note that setting the line number
1317 does not change the current position within the file/buffer being read.
1318
1319 The contents of C<$/> are used to to determine what constitutes a line
1320 terminator.
1321
1322 =head2 fileno
1323
1324     $z->fileno()
1325     fileno($z)
1326
1327 If the C<$z> object is associated with a file or a filehandle, C<fileno>
1328 will return the underlying file descriptor. Once the C<close> method is
1329 called C<fileno> will return C<undef>.
1330
1331 If the C<$z> object is is associated with a buffer, this method will return
1332 C<undef>.
1333
1334 =head2 close
1335
1336     $z->close() ;
1337     close $z ;
1338
1339 Closes the output file/buffer. 
1340
1341 For most versions of Perl this method will be automatically invoked if
1342 the IO::Uncompress::Unzip object is destroyed (either explicitly or by the
1343 variable with the reference to the object going out of scope). The
1344 exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In
1345 these cases, the C<close> method will be called automatically, but
1346 not until global destruction of all live objects when the program is
1347 terminating.
1348
1349 Therefore, if you want your scripts to be able to run on all versions
1350 of Perl, you should call C<close> explicitly and not rely on automatic
1351 closing.
1352
1353 Returns true on success, otherwise 0.
1354
1355 If the C<AutoClose> option has been enabled when the IO::Uncompress::Unzip
1356 object was created, and the object is associated with a file, the
1357 underlying file will also be closed.
1358
1359 =head2 nextStream
1360
1361 Usage is
1362
1363     my $status = $z->nextStream();
1364
1365 Skips to the next compressed data stream in the input file/buffer. If a new
1366 compressed data stream is found, the eof marker will be cleared and C<$.>
1367 will be reset to 0.
1368
1369 Returns 1 if a new stream was found, 0 if none was found, and -1 if an
1370 error was encountered.
1371
1372 =head2 trailingData
1373
1374 Usage is
1375
1376     my $data = $z->trailingData();
1377
1378 Returns the data, if any, that is present immediately after the compressed
1379 data stream once uncompression is complete. It only makes sense to call
1380 this method once the end of the compressed data stream has been
1381 encountered.
1382
1383 This option can be used when there is useful information immediately
1384 following the compressed data stream, and you don't know the length of the
1385 compressed data stream.
1386
1387 If the input is a buffer, C<trailingData> will return everything from the
1388 end of the compressed data stream to the end of the buffer.
1389
1390 If the input is a filehandle, C<trailingData> will return the data that is
1391 left in the filehandle input buffer once the end of the compressed data
1392 stream has been reached. You can then use the filehandle to read the rest
1393 of the input file. 
1394
1395 Don't bother using C<trailingData> if the input is a filename.
1396
1397 If you know the length of the compressed data stream before you start
1398 uncompressing, you can avoid having to use C<trailingData> by setting the
1399 C<InputLength> option in the constructor.
1400
1401 =head1 Importing 
1402
1403 No symbolic constants are required by this IO::Uncompress::Unzip at present. 
1404
1405 =over 5
1406
1407 =item :all
1408
1409 Imports C<unzip> and C<$UnzipError>.
1410 Same as doing this
1411
1412     use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
1413
1414 =back
1415
1416 =head1 EXAMPLES
1417
1418 =head2 Working with Net::FTP
1419
1420 See L<IO::Uncompress::Unzip::FAQ|IO::Uncompress::Unzip::FAQ/"Compressed files and Net::FTP">
1421
1422 =head1 SEE ALSO
1423
1424 L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress>
1425
1426 L<Compress::Zlib::FAQ|Compress::Zlib::FAQ>
1427
1428 L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>,
1429 L<Archive::Tar|Archive::Tar>,
1430 L<IO::Zlib|IO::Zlib>
1431
1432 For RFC 1950, 1951 and 1952 see 
1433 F<http://www.faqs.org/rfcs/rfc1950.html>,
1434 F<http://www.faqs.org/rfcs/rfc1951.html> and
1435 F<http://www.faqs.org/rfcs/rfc1952.html>
1436
1437 The I<zlib> compression library was written by Jean-loup Gailly
1438 F<gzip@prep.ai.mit.edu> and Mark Adler F<madler@alumni.caltech.edu>.
1439
1440 The primary site for the I<zlib> compression library is
1441 F<http://www.zlib.org>.
1442
1443 The primary site for gzip is F<http://www.gzip.org>.
1444
1445 =head1 AUTHOR
1446
1447 This module was written by Paul Marquess, F<pmqs@cpan.org>. 
1448
1449 =head1 MODIFICATION HISTORY
1450
1451 See the Changes file.
1452
1453 =head1 COPYRIGHT AND LICENSE
1454
1455 Copyright (c) 2005-2009 Paul Marquess. All rights reserved.
1456
1457 This program is free software; you can redistribute it and/or
1458 modify it under the same terms as Perl itself.
1459