1package IO::Uncompress::Unzip; 2 3require 5.006 ; 4 5# for RFC1952 6 7use strict ; 8use warnings; 9use bytes; 10 11use IO::File; 12use IO::Uncompress::RawInflate 2.084 ; 13use IO::Compress::Base::Common 2.084 qw(:Status ); 14use IO::Uncompress::Adapter::Inflate 2.084 ; 15use IO::Uncompress::Adapter::Identity 2.084 ; 16use IO::Compress::Zlib::Extra 2.084 ; 17use IO::Compress::Zip::Constants 2.084 ; 18 19use Compress::Raw::Zlib 2.084 () ; 20 21BEGIN 22{ 23 eval{ require IO::Uncompress::Adapter::Bunzip2 ; 24 import IO::Uncompress::Adapter::Bunzip2 } ; 25 eval{ require IO::Uncompress::Adapter::UnLzma ; 26 import IO::Uncompress::Adapter::UnLzma } ; 27} 28 29 30require Exporter ; 31 32our ($VERSION, @ISA, @EXPORT_OK, %EXPORT_TAGS, $UnzipError, %headerLookup); 33 34$VERSION = '2.084'; 35$UnzipError = ''; 36 37@ISA = qw(IO::Uncompress::RawInflate Exporter); 38@EXPORT_OK = qw( $UnzipError unzip ); 39%EXPORT_TAGS = %IO::Uncompress::RawInflate::EXPORT_TAGS ; 40push @{ $EXPORT_TAGS{all} }, @EXPORT_OK ; 41Exporter::export_ok_tags('all'); 42 43%headerLookup = ( 44 ZIP_CENTRAL_HDR_SIG, \&skipCentralDirectory, 45 ZIP_END_CENTRAL_HDR_SIG, \&skipEndCentralDirectory, 46 ZIP64_END_CENTRAL_REC_HDR_SIG, \&skipCentralDirectory64Rec, 47 ZIP64_END_CENTRAL_LOC_HDR_SIG, \&skipCentralDirectory64Loc, 48 ZIP64_ARCHIVE_EXTRA_SIG, \&skipArchiveExtra, 49 ZIP64_DIGITAL_SIGNATURE_SIG, \&skipDigitalSignature, 50 ); 51 52sub new 53{ 54 my $class = shift ; 55 my $obj = IO::Compress::Base::Common::createSelfTiedObject($class, \$UnzipError); 56 $obj->_create(undef, 0, @_); 57} 58 59sub unzip 60{ 61 my $obj = IO::Compress::Base::Common::createSelfTiedObject(undef, \$UnzipError); 62 return $obj->_inf(@_) ; 63} 64 65sub getExtraParams 66{ 67 68 return ( 69# # Zip header fields 70 'name' => [IO::Compress::Base::Common::Parse_any, undef], 71 72 'stream' => [IO::Compress::Base::Common::Parse_boolean, 0], 73 74 # TODO - This means reading the central directory to get 75 # 1. the local header offsets 76 # 2. The compressed data length 77 ); 78} 79 80sub ckParams 81{ 82 my $self = shift ; 83 my $got = shift ; 84 85 # unzip always needs crc32 86 $got->setValue('crc32' => 1); 87 88 *$self->{UnzipData}{Name} = $got->getValue('name'); 89 90 return 1; 91} 92 93sub mkUncomp 94{ 95 my $self = shift ; 96 my $got = shift ; 97 98 my $magic = $self->ckMagic() 99 or return 0; 100 101 *$self->{Info} = $self->readHeader($magic) 102 or return undef ; 103 104 return 1; 105 106} 107 108sub ckMagic 109{ 110 my $self = shift; 111 112 my $magic ; 113 $self->smartReadExact(\$magic, 4); 114 115 *$self->{HeaderPending} = $magic ; 116 117 return $self->HeaderError("Minimum header size is " . 118 4 . " bytes") 119 if length $magic != 4 ; 120 121 return $self->HeaderError("Bad Magic") 122 if ! _isZipMagic($magic) ; 123 124 *$self->{Type} = 'zip'; 125 126 return $magic ; 127} 128 129 130sub fastForward 131{ 132 my $self = shift; 133 my $offset = shift; 134 135 # TODO - if Stream isn't enabled & reading from file, use seek 136 137 my $buffer = ''; 138 my $c = 1024 * 16; 139 140 while ($offset > 0) 141 { 142 $c = length $offset 143 if length $offset < $c ; 144 145 $offset -= $c; 146 147 $self->smartReadExact(\$buffer, $c) 148 or return 0; 149 } 150 151 return 1; 152} 153 154 155sub readHeader 156{ 157 my $self = shift; 158 my $magic = shift ; 159 160 my $name = *$self->{UnzipData}{Name} ; 161 my $hdr = $self->_readZipHeader($magic) ; 162 163 while (defined $hdr) 164 { 165 if (! defined $name || $hdr->{Name} eq $name) 166 { 167 return $hdr ; 168 } 169 170 # skip the data 171 # TODO - when Stream is off, use seek 172 my $buffer; 173 if (*$self->{ZipData}{Streaming}) { 174 while (1) { 175 176 my $b; 177 my $status = $self->smartRead(\$b, 1024 * 16); 178 179 return $self->saveErrorString(undef, "Truncated file") 180 if $status <= 0 ; 181 182 my $temp_buf ; 183 my $out; 184 185 $status = *$self->{Uncomp}->uncompr(\$b, \$temp_buf, 0, $out); 186 187 return $self->saveErrorString(undef, *$self->{Uncomp}{Error}, 188 *$self->{Uncomp}{ErrorNo}) 189 if $self->saveStatus($status) == STATUS_ERROR; 190 191 $self->pushBack($b) ; 192 193 if ($status == STATUS_ENDSTREAM) { 194 *$self->{Uncomp}->reset(); 195 last; 196 } 197 } 198 199 # skip the trailer 200 $self->smartReadExact(\$buffer, $hdr->{TrailerLength}) 201 or return $self->saveErrorString(undef, "Truncated file"); 202 } 203 else { 204 my $c = $hdr->{CompressedLength}->get64bit(); 205 $self->fastForward($c) 206 or return $self->saveErrorString(undef, "Truncated file"); 207 $buffer = ''; 208 } 209 210 $self->chkTrailer($buffer) == STATUS_OK 211 or return $self->saveErrorString(undef, "Truncated file"); 212 213 $hdr = $self->_readFullZipHeader(); 214 215 return $self->saveErrorString(undef, "Cannot find '$name'") 216 if $self->smartEof(); 217 } 218 219 return undef; 220} 221 222sub chkTrailer 223{ 224 my $self = shift; 225 my $trailer = shift; 226 227 my ($sig, $CRC32, $cSize, $uSize) ; 228 my ($cSizeHi, $uSizeHi) = (0, 0); 229 if (*$self->{ZipData}{Streaming}) { 230 $sig = unpack ("V", substr($trailer, 0, 4)); 231 $CRC32 = unpack ("V", substr($trailer, 4, 4)); 232 233 if (*$self->{ZipData}{Zip64} ) { 234 $cSize = U64::newUnpack_V64 substr($trailer, 8, 8); 235 $uSize = U64::newUnpack_V64 substr($trailer, 16, 8); 236 } 237 else { 238 $cSize = U64::newUnpack_V32 substr($trailer, 8, 4); 239 $uSize = U64::newUnpack_V32 substr($trailer, 12, 4); 240 } 241 242 return $self->TrailerError("Data Descriptor signature, got $sig") 243 if $sig != ZIP_DATA_HDR_SIG; 244 } 245 else { 246 ($CRC32, $cSize, $uSize) = 247 (*$self->{ZipData}{Crc32}, 248 *$self->{ZipData}{CompressedLen}, 249 *$self->{ZipData}{UnCompressedLen}); 250 } 251 252 *$self->{Info}{CRC32} = *$self->{ZipData}{CRC32} ; 253 *$self->{Info}{CompressedLength} = $cSize->get64bit(); 254 *$self->{Info}{UncompressedLength} = $uSize->get64bit(); 255 256 if (*$self->{Strict}) { 257 return $self->TrailerError("CRC mismatch") 258 if $CRC32 != *$self->{ZipData}{CRC32} ; 259 260 return $self->TrailerError("CSIZE mismatch.") 261 if ! $cSize->equal(*$self->{CompSize}); 262 263 return $self->TrailerError("USIZE mismatch.") 264 if ! $uSize->equal(*$self->{UnCompSize}); 265 } 266 267 my $reachedEnd = STATUS_ERROR ; 268 # check for central directory or end of central directory 269 while (1) 270 { 271 my $magic ; 272 my $got = $self->smartRead(\$magic, 4); 273 274 return $self->saveErrorString(STATUS_ERROR, "Truncated file") 275 if $got != 4 && *$self->{Strict}; 276 277 if ($got == 0) { 278 return STATUS_EOF ; 279 } 280 elsif ($got < 0) { 281 return STATUS_ERROR ; 282 } 283 elsif ($got < 4) { 284 $self->pushBack($magic) ; 285 return STATUS_OK ; 286 } 287 288 my $sig = unpack("V", $magic) ; 289 290 my $hdr; 291 if ($hdr = $headerLookup{$sig}) 292 { 293 if (&$hdr($self, $magic) != STATUS_OK ) { 294 if (*$self->{Strict}) { 295 return STATUS_ERROR ; 296 } 297 else { 298 $self->clearError(); 299 return STATUS_OK ; 300 } 301 } 302 303 if ($sig == ZIP_END_CENTRAL_HDR_SIG) 304 { 305 return STATUS_OK ; 306 last; 307 } 308 } 309 elsif ($sig == ZIP_LOCAL_HDR_SIG) 310 { 311 $self->pushBack($magic) ; 312 return STATUS_OK ; 313 } 314 else 315 { 316 # put the data back 317 $self->pushBack($magic) ; 318 last; 319 } 320 } 321 322 return $reachedEnd ; 323} 324 325sub skipCentralDirectory 326{ 327 my $self = shift; 328 my $magic = shift ; 329 330 my $buffer; 331 $self->smartReadExact(\$buffer, 46 - 4) 332 or return $self->TrailerError("Minimum header size is " . 333 46 . " bytes") ; 334 335 my $keep = $magic . $buffer ; 336 *$self->{HeaderPending} = $keep ; 337 338 #my $versionMadeBy = unpack ("v", substr($buffer, 4-4, 2)); 339 #my $extractVersion = unpack ("v", substr($buffer, 6-4, 2)); 340 #my $gpFlag = unpack ("v", substr($buffer, 8-4, 2)); 341 #my $compressedMethod = unpack ("v", substr($buffer, 10-4, 2)); 342 #my $lastModTime = unpack ("V", substr($buffer, 12-4, 4)); 343 #my $crc32 = unpack ("V", substr($buffer, 16-4, 4)); 344 my $compressedLength = unpack ("V", substr($buffer, 20-4, 4)); 345 my $uncompressedLength = unpack ("V", substr($buffer, 24-4, 4)); 346 my $filename_length = unpack ("v", substr($buffer, 28-4, 2)); 347 my $extra_length = unpack ("v", substr($buffer, 30-4, 2)); 348 my $comment_length = unpack ("v", substr($buffer, 32-4, 2)); 349 #my $disk_start = unpack ("v", substr($buffer, 34-4, 2)); 350 #my $int_file_attrib = unpack ("v", substr($buffer, 36-4, 2)); 351 #my $ext_file_attrib = unpack ("V", substr($buffer, 38-4, 2)); 352 #my $lcl_hdr_offset = unpack ("V", substr($buffer, 42-4, 2)); 353 354 355 my $filename; 356 my $extraField; 357 my $comment ; 358 if ($filename_length) 359 { 360 $self->smartReadExact(\$filename, $filename_length) 361 or return $self->TruncatedTrailer("filename"); 362 $keep .= $filename ; 363 } 364 365 if ($extra_length) 366 { 367 $self->smartReadExact(\$extraField, $extra_length) 368 or return $self->TruncatedTrailer("extra"); 369 $keep .= $extraField ; 370 } 371 372 if ($comment_length) 373 { 374 $self->smartReadExact(\$comment, $comment_length) 375 or return $self->TruncatedTrailer("comment"); 376 $keep .= $comment ; 377 } 378 379 return STATUS_OK ; 380} 381 382sub skipArchiveExtra 383{ 384 my $self = shift; 385 my $magic = shift ; 386 387 my $buffer; 388 $self->smartReadExact(\$buffer, 4) 389 or return $self->TrailerError("Minimum header size is " . 390 4 . " bytes") ; 391 392 my $keep = $magic . $buffer ; 393 394 my $size = unpack ("V", $buffer); 395 396 $self->smartReadExact(\$buffer, $size) 397 or return $self->TrailerError("Minimum header size is " . 398 $size . " bytes") ; 399 400 $keep .= $buffer ; 401 *$self->{HeaderPending} = $keep ; 402 403 return STATUS_OK ; 404} 405 406 407sub skipCentralDirectory64Rec 408{ 409 my $self = shift; 410 my $magic = shift ; 411 412 my $buffer; 413 $self->smartReadExact(\$buffer, 8) 414 or return $self->TrailerError("Minimum header size is " . 415 8 . " bytes") ; 416 417 my $keep = $magic . $buffer ; 418 419 my ($sizeLo, $sizeHi) = unpack ("V V", $buffer); 420 my $size = $sizeHi * U64::MAX32 + $sizeLo; 421 422 $self->fastForward($size) 423 or return $self->TrailerError("Minimum header size is " . 424 $size . " bytes") ; 425 426 #$keep .= $buffer ; 427 #*$self->{HeaderPending} = $keep ; 428 429 #my $versionMadeBy = unpack ("v", substr($buffer, 0, 2)); 430 #my $extractVersion = unpack ("v", substr($buffer, 2, 2)); 431 #my $diskNumber = unpack ("V", substr($buffer, 4, 4)); 432 #my $cntrlDirDiskNo = unpack ("V", substr($buffer, 8, 4)); 433 #my $entriesInThisCD = unpack ("V V", substr($buffer, 12, 8)); 434 #my $entriesInCD = unpack ("V V", substr($buffer, 20, 8)); 435 #my $sizeOfCD = unpack ("V V", substr($buffer, 28, 8)); 436 #my $offsetToCD = unpack ("V V", substr($buffer, 36, 8)); 437 438 return STATUS_OK ; 439} 440 441sub skipCentralDirectory64Loc 442{ 443 my $self = shift; 444 my $magic = shift ; 445 446 my $buffer; 447 $self->smartReadExact(\$buffer, 20 - 4) 448 or return $self->TrailerError("Minimum header size is " . 449 20 . " bytes") ; 450 451 my $keep = $magic . $buffer ; 452 *$self->{HeaderPending} = $keep ; 453 454 #my $startCdDisk = unpack ("V", substr($buffer, 4-4, 4)); 455 #my $offsetToCD = unpack ("V V", substr($buffer, 8-4, 8)); 456 #my $diskCount = unpack ("V", substr($buffer, 16-4, 4)); 457 458 return STATUS_OK ; 459} 460 461sub skipEndCentralDirectory 462{ 463 my $self = shift; 464 my $magic = shift ; 465 466 467 my $buffer; 468 $self->smartReadExact(\$buffer, 22 - 4) 469 or return $self->TrailerError("Minimum header size is " . 470 22 . " bytes") ; 471 472 my $keep = $magic . $buffer ; 473 *$self->{HeaderPending} = $keep ; 474 475 #my $diskNumber = unpack ("v", substr($buffer, 4-4, 2)); 476 #my $cntrlDirDiskNo = unpack ("v", substr($buffer, 6-4, 2)); 477 #my $entriesInThisCD = unpack ("v", substr($buffer, 8-4, 2)); 478 #my $entriesInCD = unpack ("v", substr($buffer, 10-4, 2)); 479 #my $sizeOfCD = unpack ("V", substr($buffer, 12-4, 4)); 480 #my $offsetToCD = unpack ("V", substr($buffer, 16-4, 4)); 481 my $comment_length = unpack ("v", substr($buffer, 20-4, 2)); 482 483 484 my $comment ; 485 if ($comment_length) 486 { 487 $self->smartReadExact(\$comment, $comment_length) 488 or return $self->TruncatedTrailer("comment"); 489 $keep .= $comment ; 490 } 491 492 return STATUS_OK ; 493} 494 495 496sub _isZipMagic 497{ 498 my $buffer = shift ; 499 return 0 if length $buffer < 4 ; 500 my $sig = unpack("V", $buffer) ; 501 return $sig == ZIP_LOCAL_HDR_SIG ; 502} 503 504 505sub _readFullZipHeader($) 506{ 507 my ($self) = @_ ; 508 my $magic = '' ; 509 510 $self->smartReadExact(\$magic, 4); 511 512 *$self->{HeaderPending} = $magic ; 513 514 return $self->HeaderError("Minimum header size is " . 515 30 . " bytes") 516 if length $magic != 4 ; 517 518 519 return $self->HeaderError("Bad Magic") 520 if ! _isZipMagic($magic) ; 521 522 my $status = $self->_readZipHeader($magic); 523 delete *$self->{Transparent} if ! defined $status ; 524 return $status ; 525} 526 527sub _readZipHeader($) 528{ 529 my ($self, $magic) = @_ ; 530 my ($HeaderCRC) ; 531 my ($buffer) = '' ; 532 533 $self->smartReadExact(\$buffer, 30 - 4) 534 or return $self->HeaderError("Minimum header size is " . 535 30 . " bytes") ; 536 537 my $keep = $magic . $buffer ; 538 *$self->{HeaderPending} = $keep ; 539 540 my $extractVersion = unpack ("v", substr($buffer, 4-4, 2)); 541 my $gpFlag = unpack ("v", substr($buffer, 6-4, 2)); 542 my $compressedMethod = unpack ("v", substr($buffer, 8-4, 2)); 543 my $lastModTime = unpack ("V", substr($buffer, 10-4, 4)); 544 my $crc32 = unpack ("V", substr($buffer, 14-4, 4)); 545 my $compressedLength = U64::newUnpack_V32 substr($buffer, 18-4, 4); 546 my $uncompressedLength = U64::newUnpack_V32 substr($buffer, 22-4, 4); 547 my $filename_length = unpack ("v", substr($buffer, 26-4, 2)); 548 my $extra_length = unpack ("v", substr($buffer, 28-4, 2)); 549 550 my $filename; 551 my $extraField; 552 my @EXTRA = (); 553 my $streamingMode = ($gpFlag & ZIP_GP_FLAG_STREAMING_MASK) ? 1 : 0 ; 554 555 return $self->HeaderError("Encrypted content not supported") 556 if $gpFlag & (ZIP_GP_FLAG_ENCRYPTED_MASK|ZIP_GP_FLAG_STRONG_ENCRYPTED_MASK); 557 558 return $self->HeaderError("Patch content not supported") 559 if $gpFlag & ZIP_GP_FLAG_PATCHED_MASK; 560 561 *$self->{ZipData}{Streaming} = $streamingMode; 562 563 564 if ($filename_length) 565 { 566 $self->smartReadExact(\$filename, $filename_length) 567 or return $self->TruncatedHeader("Filename"); 568 $keep .= $filename ; 569 } 570 571 my $zip64 = 0 ; 572 573 if ($extra_length) 574 { 575 $self->smartReadExact(\$extraField, $extra_length) 576 or return $self->TruncatedHeader("Extra Field"); 577 578 my $bad = IO::Compress::Zlib::Extra::parseRawExtra($extraField, 579 \@EXTRA, 1, 0); 580 return $self->HeaderError($bad) 581 if defined $bad; 582 583 $keep .= $extraField ; 584 585 my %Extra ; 586 for (@EXTRA) 587 { 588 $Extra{$_->[0]} = \$_->[1]; 589 } 590 591 if (defined $Extra{ZIP_EXTRA_ID_ZIP64()}) 592 { 593 $zip64 = 1 ; 594 595 my $buff = ${ $Extra{ZIP_EXTRA_ID_ZIP64()} }; 596 597 # This code assumes that all the fields in the Zip64 598 # extra field aren't necessarily present. The spec says that 599 # they only exist if the equivalent local headers are -1. 600 601 if (! $streamingMode) { 602 my $offset = 0 ; 603 604 if (U64::full32 $uncompressedLength->get32bit() ) { 605 $uncompressedLength 606 = U64::newUnpack_V64 substr($buff, 0, 8); 607 608 $offset += 8 ; 609 } 610 611 if (U64::full32 $compressedLength->get32bit() ) { 612 613 $compressedLength 614 = U64::newUnpack_V64 substr($buff, $offset, 8); 615 616 $offset += 8 ; 617 } 618 } 619 } 620 } 621 622 *$self->{ZipData}{Zip64} = $zip64; 623 624 if (! $streamingMode) { 625 *$self->{ZipData}{Streaming} = 0; 626 *$self->{ZipData}{Crc32} = $crc32; 627 *$self->{ZipData}{CompressedLen} = $compressedLength; 628 *$self->{ZipData}{UnCompressedLen} = $uncompressedLength; 629 *$self->{CompressedInputLengthRemaining} = 630 *$self->{CompressedInputLength} = $compressedLength->get64bit(); 631 } 632 633 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(undef); 634 *$self->{ZipData}{Method} = $compressedMethod; 635 if ($compressedMethod == ZIP_CM_DEFLATE) 636 { 637 *$self->{Type} = 'zip-deflate'; 638 my $obj = IO::Uncompress::Adapter::Inflate::mkUncompObject(1,0,0); 639 640 *$self->{Uncomp} = $obj; 641 } 642 elsif ($compressedMethod == ZIP_CM_BZIP2) 643 { 644 return $self->HeaderError("Unsupported Compression format $compressedMethod") 645 if ! defined $IO::Uncompress::Adapter::Bunzip2::VERSION ; 646 647 *$self->{Type} = 'zip-bzip2'; 648 649 my $obj = IO::Uncompress::Adapter::Bunzip2::mkUncompObject(); 650 651 *$self->{Uncomp} = $obj; 652 } 653 elsif ($compressedMethod == ZIP_CM_LZMA) 654 { 655 return $self->HeaderError("Unsupported Compression format $compressedMethod") 656 if ! defined $IO::Uncompress::Adapter::UnLzma::VERSION ; 657 658 *$self->{Type} = 'zip-lzma'; 659 my $LzmaHeader; 660 $self->smartReadExact(\$LzmaHeader, 4) 661 or return $self->saveErrorString(undef, "Truncated file"); 662 my ($verHi, $verLo) = unpack ("CC", substr($LzmaHeader, 0, 2)); 663 my $LzmaPropertiesSize = unpack ("v", substr($LzmaHeader, 2, 2)); 664 665 666 my $LzmaPropertyData; 667 $self->smartReadExact(\$LzmaPropertyData, $LzmaPropertiesSize) 668 or return $self->saveErrorString(undef, "Truncated file"); 669 670 if (! $streamingMode) { 671 *$self->{ZipData}{CompressedLen}->subtract(4 + $LzmaPropertiesSize) ; 672 *$self->{CompressedInputLengthRemaining} = 673 *$self->{CompressedInputLength} = *$self->{ZipData}{CompressedLen}->get64bit(); 674 } 675 676 my $obj = 677 IO::Uncompress::Adapter::UnLzma::mkUncompZipObject($LzmaPropertyData); 678 679 *$self->{Uncomp} = $obj; 680 } 681 elsif ($compressedMethod == ZIP_CM_STORE) 682 { 683 *$self->{Type} = 'zip-stored'; 684 685 my $obj = 686 IO::Uncompress::Adapter::Identity::mkUncompObject($streamingMode, 687 $zip64); 688 689 *$self->{Uncomp} = $obj; 690 } 691 else 692 { 693 return $self->HeaderError("Unsupported Compression format $compressedMethod"); 694 } 695 696 return { 697 'Type' => 'zip', 698 'FingerprintLength' => 4, 699 #'HeaderLength' => $compressedMethod == 8 ? length $keep : 0, 700 'HeaderLength' => length $keep, 701 'Zip64' => $zip64, 702 'TrailerLength' => ! $streamingMode ? 0 : $zip64 ? 24 : 16, 703 'Header' => $keep, 704 'CompressedLength' => $compressedLength , 705 'UncompressedLength' => $uncompressedLength , 706 'CRC32' => $crc32 , 707 'Name' => $filename, 708 'Time' => _dosToUnixTime($lastModTime), 709 'Stream' => $streamingMode, 710 711 'MethodID' => $compressedMethod, 712 'MethodName' => $compressedMethod == ZIP_CM_DEFLATE 713 ? "Deflated" 714 : $compressedMethod == ZIP_CM_BZIP2 715 ? "Bzip2" 716 : $compressedMethod == ZIP_CM_LZMA 717 ? "Lzma" 718 : $compressedMethod == ZIP_CM_STORE 719 ? "Stored" 720 : "Unknown" , 721 722# 'TextFlag' => $flag & GZIP_FLG_FTEXT ? 1 : 0, 723# 'HeaderCRCFlag' => $flag & GZIP_FLG_FHCRC ? 1 : 0, 724# 'NameFlag' => $flag & GZIP_FLG_FNAME ? 1 : 0, 725# 'CommentFlag' => $flag & GZIP_FLG_FCOMMENT ? 1 : 0, 726# 'ExtraFlag' => $flag & GZIP_FLG_FEXTRA ? 1 : 0, 727# 'Comment' => $comment, 728# 'OsID' => $os, 729# 'OsName' => defined $GZIP_OS_Names{$os} 730# ? $GZIP_OS_Names{$os} : "Unknown", 731# 'HeaderCRC' => $HeaderCRC, 732# 'Flags' => $flag, 733# 'ExtraFlags' => $xfl, 734 'ExtraFieldRaw' => $extraField, 735 'ExtraField' => [ @EXTRA ], 736 737 738 } 739} 740 741sub filterUncompressed 742{ 743 my $self = shift ; 744 745 if (*$self->{ZipData}{Method} == ZIP_CM_DEFLATE) { 746 *$self->{ZipData}{CRC32} = *$self->{Uncomp}->crc32() ; 747 } 748 else { 749 *$self->{ZipData}{CRC32} = Compress::Raw::Zlib::crc32(${$_[0]}, *$self->{ZipData}{CRC32}, $_[1]); 750 } 751} 752 753 754# from Archive::Zip & info-zip 755sub _dosToUnixTime 756{ 757 my $dt = shift; 758 759 my $year = ( ( $dt >> 25 ) & 0x7f ) + 80; 760 my $mon = ( ( $dt >> 21 ) & 0x0f ) - 1; 761 my $mday = ( ( $dt >> 16 ) & 0x1f ); 762 763 my $hour = ( ( $dt >> 11 ) & 0x1f ); 764 my $min = ( ( $dt >> 5 ) & 0x3f ); 765 my $sec = ( ( $dt << 1 ) & 0x3e ); 766 767 768 use POSIX 'mktime'; 769 770 my $time_t = mktime( $sec, $min, $hour, $mday, $mon, $year, 0, 0, -1 ); 771 return 0 if ! defined $time_t; 772 return $time_t; 773} 774 775#sub scanCentralDirectory 776#{ 777# # Use cases 778# # 1 32-bit CD 779# # 2 64-bit CD 780# 781# my $self = shift ; 782# 783# my @CD = (); 784# my $offset = $self->findCentralDirectoryOffset(); 785# 786# return 0 787# if ! defined $offset; 788# 789# $self->smarkSeek($offset, 0, SEEK_SET) ; 790# 791# # Now walk the Central Directory Records 792# my $buffer ; 793# while ($self->smartReadExact(\$buffer, 46) && 794# unpack("V", $buffer) == ZIP_CENTRAL_HDR_SIG) { 795# 796# my $compressedLength = unpack ("V", substr($buffer, 20, 4)); 797# my $filename_length = unpack ("v", substr($buffer, 28, 2)); 798# my $extra_length = unpack ("v", substr($buffer, 30, 2)); 799# my $comment_length = unpack ("v", substr($buffer, 32, 2)); 800# 801# $self->smarkSeek($filename_length + $extra_length + $comment_length, 0, SEEK_CUR) 802# if $extra_length || $comment_length || $filename_length; 803# push @CD, $compressedLength ; 804# } 805# 806#} 807# 808#sub findCentralDirectoryOffset 809#{ 810# my $self = shift ; 811# 812# # Most common use-case is where there is no comment, so 813# # know exactly where the end of central directory record 814# # should be. 815# 816# $self->smarkSeek(-22, 0, SEEK_END) ; 817# 818# my $buffer; 819# $self->smartReadExact(\$buffer, 22) ; 820# 821# my $zip64 = 0; 822# my $centralDirOffset ; 823# if ( unpack("V", $buffer) == ZIP_END_CENTRAL_HDR_SIG ) { 824# $centralDirOffset = unpack ("V", substr($buffer, 16, 2)); 825# } 826# else { 827# die "xxxx"; 828# } 829# 830# return $centralDirOffset ; 831#} 832# 833#sub is84BitCD 834#{ 835# # TODO 836# my $self = shift ; 837#} 838 839 840sub skip 841{ 842 my $self = shift; 843 my $size = shift; 844 845 use Fcntl qw(SEEK_CUR); 846 if (ref $size eq 'U64') { 847 $self->smartSeek($size->get64bit(), SEEK_CUR); 848 } 849 else { 850 $self->smartSeek($size, SEEK_CUR); 851 } 852 853} 854 855 856sub scanCentralDirectory 857{ 858 my $self = shift; 859 860 my $here = $self->tell(); 861 862 # Use cases 863 # 1 32-bit CD 864 # 2 64-bit CD 865 866 my @CD = (); 867 my $offset = $self->findCentralDirectoryOffset(); 868 869 return () 870 if ! defined $offset; 871 872 $self->smarkSeek($offset, 0, SEEK_SET) ; 873 874 # Now walk the Central Directory Records 875 my $buffer ; 876 while ($self->smartReadExact(\$buffer, 46) && 877 unpack("V", $buffer) == ZIP_CENTRAL_HDR_SIG) { 878 879 my $compressedLength = unpack("V", substr($buffer, 20, 4)); 880 my $uncompressedLength = unpack("V", substr($buffer, 24, 4)); 881 my $filename_length = unpack("v", substr($buffer, 28, 2)); 882 my $extra_length = unpack("v", substr($buffer, 30, 2)); 883 my $comment_length = unpack("v", substr($buffer, 32, 2)); 884 885 $self->skip($filename_length ) ; 886 887 my $v64 = new U64 $compressedLength ; 888 889 if (U64::full32 $compressedLength ) { 890 $self->smartReadExact(\$buffer, $extra_length) ; 891 die "xxx $offset $comment_length $filename_length $extra_length" . length($buffer) 892 if length($buffer) != $extra_length; 893 my $got = $self->get64Extra($buffer, U64::full32 $uncompressedLength); 894 895 # If not Zip64 extra field, assume size is 0xFFFFFFFF 896 $v64 = $got if defined $got; 897 } 898 else { 899 $self->skip($extra_length) ; 900 } 901 902 $self->skip($comment_length ) ; 903 904 push @CD, $v64 ; 905 } 906 907 $self->smartSeek($here, 0, SEEK_SET) ; 908 909 return @CD; 910} 911 912sub get64Extra 913{ 914 my $self = shift ; 915 916 my $buffer = shift; 917 my $is_uncomp = shift ; 918 919 my $extra = IO::Compress::Zlib::Extra::findID(0x0001, $buffer); 920 921 if (! defined $extra) 922 { 923 return undef; 924 } 925 else 926 { 927 my $u64 = U64::newUnpack_V64(substr($extra, $is_uncomp ? 8 : 0)) ; 928 return $u64; 929 } 930} 931 932sub offsetFromZip64 933{ 934 my $self = shift ; 935 my $here = shift; 936 937 $self->smartSeek($here - 20, 0, SEEK_SET) 938 or die "xx $!" ; 939 940 my $buffer; 941 my $got = 0; 942 $self->smartReadExact(\$buffer, 20) 943 or die "xxx $here $got $!" ; 944 945 if ( unpack("V", $buffer) == ZIP64_END_CENTRAL_LOC_HDR_SIG ) { 946 my $cd64 = U64::Value_VV64 substr($buffer, 8, 8); 947 948 $self->smartSeek($cd64, 0, SEEK_SET) ; 949 950 $self->smartReadExact(\$buffer, 4) 951 or die "xxx" ; 952 953 if ( unpack("V", $buffer) == ZIP64_END_CENTRAL_REC_HDR_SIG ) { 954 955 $self->smartReadExact(\$buffer, 8) 956 or die "xxx" ; 957 my $size = U64::Value_VV64($buffer); 958 $self->smartReadExact(\$buffer, $size) 959 or die "xxx" ; 960 961 my $cd64 = U64::Value_VV64 substr($buffer, 36, 8); 962 963 return $cd64 ; 964 } 965 966 die "zzz"; 967 } 968 969 die "zzz"; 970} 971 972use constant Pack_ZIP_END_CENTRAL_HDR_SIG => pack("V", ZIP_END_CENTRAL_HDR_SIG); 973 974sub findCentralDirectoryOffset 975{ 976 my $self = shift ; 977 978 # Most common use-case is where there is no comment, so 979 # know exactly where the end of central directory record 980 # should be. 981 982 $self->smartSeek(-22, 0, SEEK_END) ; 983 my $here = $self->tell(); 984 985 my $buffer; 986 $self->smartReadExact(\$buffer, 22) 987 or die "xxx" ; 988 989 my $zip64 = 0; 990 my $centralDirOffset ; 991 if ( unpack("V", $buffer) == ZIP_END_CENTRAL_HDR_SIG ) { 992 $centralDirOffset = unpack("V", substr($buffer, 16, 4)); 993 } 994 else { 995 $self->smartSeek(0, 0, SEEK_END) ; 996 997 my $fileLen = $self->tell(); 998 my $want = 0 ; 999 1000 while(1) { 1001 $want += 1024; 1002 my $seekTo = $fileLen - $want; 1003 if ($seekTo < 0 ) { 1004 $seekTo = 0; 1005 $want = $fileLen ; 1006 } 1007 $self->smartSeek( $seekTo, 0, SEEK_SET) 1008 or die "xxx $!" ; 1009 my $got; 1010 $self->smartReadExact($buffer, $want) 1011 or die "xxx " ; 1012 my $pos = rindex( $buffer, Pack_ZIP_END_CENTRAL_HDR_SIG); 1013 1014 if ($pos >= 0) { 1015 #$here = $self->tell(); 1016 $here = $seekTo + $pos ; 1017 $centralDirOffset = unpack("V", substr($buffer, $pos + 16, 4)); 1018 last ; 1019 } 1020 1021 return undef 1022 if $want == $fileLen; 1023 } 1024 } 1025 1026 $centralDirOffset = $self->offsetFromZip64($here) 1027 if U64::full32 $centralDirOffset ; 1028 1029 return $centralDirOffset ; 1030} 1031 10321; 1033 1034__END__ 1035 1036 1037=head1 NAME 1038 1039IO::Uncompress::Unzip - Read zip files/buffers 1040 1041=head1 SYNOPSIS 1042 1043 use IO::Uncompress::Unzip qw(unzip $UnzipError) ; 1044 1045 my $status = unzip $input => $output [,OPTS] 1046 or die "unzip failed: $UnzipError\n"; 1047 1048 my $z = new IO::Uncompress::Unzip $input [OPTS] 1049 or die "unzip failed: $UnzipError\n"; 1050 1051 $status = $z->read($buffer) 1052 $status = $z->read($buffer, $length) 1053 $status = $z->read($buffer, $length, $offset) 1054 $line = $z->getline() 1055 $char = $z->getc() 1056 $char = $z->ungetc() 1057 $char = $z->opened() 1058 1059 $status = $z->inflateSync() 1060 1061 $data = $z->trailingData() 1062 $status = $z->nextStream() 1063 $data = $z->getHeaderInfo() 1064 $z->tell() 1065 $z->seek($position, $whence) 1066 $z->binmode() 1067 $z->fileno() 1068 $z->eof() 1069 $z->close() 1070 1071 $UnzipError ; 1072 1073 # IO::File mode 1074 1075 <$z> 1076 read($z, $buffer); 1077 read($z, $buffer, $length); 1078 read($z, $buffer, $length, $offset); 1079 tell($z) 1080 seek($z, $position, $whence) 1081 binmode($z) 1082 fileno($z) 1083 eof($z) 1084 close($z) 1085 1086=head1 DESCRIPTION 1087 1088This module provides a Perl interface that allows the reading of 1089zlib files/buffers. 1090 1091For writing zip files/buffers, see the companion module IO::Compress::Zip. 1092 1093=head1 Functional Interface 1094 1095A top-level function, C<unzip>, is provided to carry out 1096"one-shot" uncompression between buffers and/or files. For finer 1097control over the uncompression process, see the L</"OO Interface"> 1098section. 1099 1100 use IO::Uncompress::Unzip qw(unzip $UnzipError) ; 1101 1102 unzip $input_filename_or_reference => $output_filename_or_reference [,OPTS] 1103 or die "unzip failed: $UnzipError\n"; 1104 1105The functional interface needs Perl5.005 or better. 1106 1107=head2 unzip $input_filename_or_reference => $output_filename_or_reference [, OPTS] 1108 1109C<unzip> expects at least two parameters, 1110C<$input_filename_or_reference> and C<$output_filename_or_reference>. 1111 1112=head3 The C<$input_filename_or_reference> parameter 1113 1114The parameter, C<$input_filename_or_reference>, is used to define the 1115source of the compressed data. 1116 1117It can take one of the following forms: 1118 1119=over 5 1120 1121=item A filename 1122 1123If the <$input_filename_or_reference> parameter is a simple scalar, it is 1124assumed to be a filename. This file will be opened for reading and the 1125input data will be read from it. 1126 1127=item A filehandle 1128 1129If the C<$input_filename_or_reference> parameter is a filehandle, the input 1130data will be read from it. The string '-' can be used as an alias for 1131standard input. 1132 1133=item A scalar reference 1134 1135If C<$input_filename_or_reference> is a scalar reference, the input data 1136will be read from C<$$input_filename_or_reference>. 1137 1138=item An array reference 1139 1140If C<$input_filename_or_reference> is an array reference, each element in 1141the array must be a filename. 1142 1143The input data will be read from each file in turn. 1144 1145The complete array will be walked to ensure that it only 1146contains valid filenames before any data is uncompressed. 1147 1148=item An Input FileGlob string 1149 1150If C<$input_filename_or_reference> is a string that is delimited by the 1151characters "<" and ">" C<unzip> will assume that it is an 1152I<input fileglob string>. The input is the list of files that match the 1153fileglob. 1154 1155See L<File::GlobMapper|File::GlobMapper> for more details. 1156 1157=back 1158 1159If the C<$input_filename_or_reference> parameter is any other type, 1160C<undef> will be returned. 1161 1162=head3 The C<$output_filename_or_reference> parameter 1163 1164The parameter C<$output_filename_or_reference> is used to control the 1165destination of the uncompressed data. This parameter can take one of 1166these forms. 1167 1168=over 5 1169 1170=item A filename 1171 1172If the C<$output_filename_or_reference> parameter is a simple scalar, it is 1173assumed to be a filename. This file will be opened for writing and the 1174uncompressed data will be written to it. 1175 1176=item A filehandle 1177 1178If the C<$output_filename_or_reference> parameter is a filehandle, the 1179uncompressed data will be written to it. The string '-' can be used as 1180an alias for standard output. 1181 1182=item A scalar reference 1183 1184If C<$output_filename_or_reference> is a scalar reference, the 1185uncompressed data will be stored in C<$$output_filename_or_reference>. 1186 1187=item An Array Reference 1188 1189If C<$output_filename_or_reference> is an array reference, 1190the uncompressed data will be pushed onto the array. 1191 1192=item An Output FileGlob 1193 1194If C<$output_filename_or_reference> is a string that is delimited by the 1195characters "<" and ">" C<unzip> will assume that it is an 1196I<output fileglob string>. The output is the list of files that match the 1197fileglob. 1198 1199When C<$output_filename_or_reference> is an fileglob string, 1200C<$input_filename_or_reference> must also be a fileglob string. Anything 1201else is an error. 1202 1203See L<File::GlobMapper|File::GlobMapper> for more details. 1204 1205=back 1206 1207If the C<$output_filename_or_reference> parameter is any other type, 1208C<undef> will be returned. 1209 1210=head2 Notes 1211 1212When C<$input_filename_or_reference> maps to multiple compressed 1213files/buffers and C<$output_filename_or_reference> is 1214a single file/buffer, after uncompression C<$output_filename_or_reference> will contain a 1215concatenation of all the uncompressed data from each of the input 1216files/buffers. 1217 1218=head2 Optional Parameters 1219 1220Unless specified below, the optional parameters for C<unzip>, 1221C<OPTS>, are the same as those used with the OO interface defined in the 1222L</"Constructor Options"> section below. 1223 1224=over 5 1225 1226=item C<< AutoClose => 0|1 >> 1227 1228This option applies to any input or output data streams to 1229C<unzip> that are filehandles. 1230 1231If C<AutoClose> is specified, and the value is true, it will result in all 1232input and/or output filehandles being closed once C<unzip> has 1233completed. 1234 1235This parameter defaults to 0. 1236 1237=item C<< BinModeOut => 0|1 >> 1238 1239This option is now a no-op. All files will be written in binmode. 1240 1241=item C<< Append => 0|1 >> 1242 1243The behaviour of this option is dependent on the type of output data 1244stream. 1245 1246=over 5 1247 1248=item * A Buffer 1249 1250If C<Append> is enabled, all uncompressed data will be append to the end of 1251the output buffer. Otherwise the output buffer will be cleared before any 1252uncompressed data is written to it. 1253 1254=item * A Filename 1255 1256If C<Append> is enabled, the file will be opened in append mode. Otherwise 1257the contents of the file, if any, will be truncated before any uncompressed 1258data is written to it. 1259 1260=item * A Filehandle 1261 1262If C<Append> is enabled, the filehandle will be positioned to the end of 1263the file via a call to C<seek> before any uncompressed data is 1264written to it. Otherwise the file pointer will not be moved. 1265 1266=back 1267 1268When C<Append> is specified, and set to true, it will I<append> all uncompressed 1269data to the output data stream. 1270 1271So when the output is a filehandle it will carry out a seek to the eof 1272before writing any uncompressed data. If the output is a filename, it will be opened for 1273appending. If the output is a buffer, all uncompressed data will be 1274appended to the existing buffer. 1275 1276Conversely when C<Append> is not specified, or it is present and is set to 1277false, it will operate as follows. 1278 1279When the output is a filename, it will truncate the contents of the file 1280before writing any uncompressed data. If the output is a filehandle 1281its position will not be changed. If the output is a buffer, it will be 1282wiped before any uncompressed data is output. 1283 1284Defaults to 0. 1285 1286=item C<< MultiStream => 0|1 >> 1287 1288If the input file/buffer contains multiple compressed data streams, this 1289option will uncompress the whole lot as a single data stream. 1290 1291Defaults to 0. 1292 1293=item C<< TrailingData => $scalar >> 1294 1295Returns the data, if any, that is present immediately after the compressed 1296data stream once uncompression is complete. 1297 1298This option can be used when there is useful information immediately 1299following the compressed data stream, and you don't know the length of the 1300compressed data stream. 1301 1302If the input is a buffer, C<trailingData> will return everything from the 1303end of the compressed data stream to the end of the buffer. 1304 1305If the input is a filehandle, C<trailingData> will return the data that is 1306left in the filehandle input buffer once the end of the compressed data 1307stream has been reached. You can then use the filehandle to read the rest 1308of the input file. 1309 1310Don't bother using C<trailingData> if the input is a filename. 1311 1312If you know the length of the compressed data stream before you start 1313uncompressing, you can avoid having to use C<trailingData> by setting the 1314C<InputLength> option. 1315 1316=back 1317 1318=head2 Examples 1319 1320Say you have a zip file, C<file1.zip>, that only contains a 1321single member, you can read it and write the uncompressed data to the 1322file C<file1.txt> like this. 1323 1324 use strict ; 1325 use warnings ; 1326 use IO::Uncompress::Unzip qw(unzip $UnzipError) ; 1327 1328 my $input = "file1.zip"; 1329 my $output = "file1.txt"; 1330 unzip $input => $output 1331 or die "unzip failed: $UnzipError\n"; 1332 1333If you have a zip file that contains multiple members and want to read a 1334specific member from the file, say C<"data1">, use the C<Name> option 1335 1336 use strict ; 1337 use warnings ; 1338 use IO::Uncompress::Unzip qw(unzip $UnzipError) ; 1339 1340 my $input = "file1.zip"; 1341 my $output = "file1.txt"; 1342 unzip $input => $output, Name => "data1" 1343 or die "unzip failed: $UnzipError\n"; 1344 1345Alternatively, if you want to read the C<"data1"> member into memory, use 1346a scalar reference for the C<output> parameter. 1347 1348 use strict ; 1349 use warnings ; 1350 use IO::Uncompress::Unzip qw(unzip $UnzipError) ; 1351 1352 my $input = "file1.zip"; 1353 my $output ; 1354 unzip $input => \$output, Name => "data1" 1355 or die "unzip failed: $UnzipError\n"; 1356 # $output now contains the uncompressed data 1357 1358To read from an existing Perl filehandle, C<$input>, and write the 1359uncompressed data to a buffer, C<$buffer>. 1360 1361 use strict ; 1362 use warnings ; 1363 use IO::Uncompress::Unzip qw(unzip $UnzipError) ; 1364 use IO::File ; 1365 1366 my $input = new IO::File "<file1.zip" 1367 or die "Cannot open 'file1.zip': $!\n" ; 1368 my $buffer ; 1369 unzip $input => \$buffer 1370 or die "unzip failed: $UnzipError\n"; 1371 1372=head1 OO Interface 1373 1374=head2 Constructor 1375 1376The format of the constructor for IO::Uncompress::Unzip is shown below 1377 1378 my $z = new IO::Uncompress::Unzip $input [OPTS] 1379 or die "IO::Uncompress::Unzip failed: $UnzipError\n"; 1380 1381Returns an C<IO::Uncompress::Unzip> object on success and undef on failure. 1382The variable C<$UnzipError> will contain an error message on failure. 1383 1384If you are running Perl 5.005 or better the object, C<$z>, returned from 1385IO::Uncompress::Unzip can be used exactly like an L<IO::File|IO::File> filehandle. 1386This means that all normal input file operations can be carried out with 1387C<$z>. For example, to read a line from a compressed file/buffer you can 1388use either of these forms 1389 1390 $line = $z->getline(); 1391 $line = <$z>; 1392 1393The mandatory parameter C<$input> is used to determine the source of the 1394compressed data. This parameter can take one of three forms. 1395 1396=over 5 1397 1398=item A filename 1399 1400If the C<$input> parameter is a scalar, it is assumed to be a filename. This 1401file will be opened for reading and the compressed data will be read from it. 1402 1403=item A filehandle 1404 1405If the C<$input> parameter is a filehandle, the compressed data will be 1406read from it. 1407The string '-' can be used as an alias for standard input. 1408 1409=item A scalar reference 1410 1411If C<$input> is a scalar reference, the compressed data will be read from 1412C<$$input>. 1413 1414=back 1415 1416=head2 Constructor Options 1417 1418The option names defined below are case insensitive and can be optionally 1419prefixed by a '-'. So all of the following are valid 1420 1421 -AutoClose 1422 -autoclose 1423 AUTOCLOSE 1424 autoclose 1425 1426OPTS is a combination of the following options: 1427 1428=over 5 1429 1430=item C<< Name => "membername" >> 1431 1432Open "membername" from the zip file for reading. 1433 1434=item C<< AutoClose => 0|1 >> 1435 1436This option is only valid when the C<$input> parameter is a filehandle. If 1437specified, and the value is true, it will result in the file being closed once 1438either the C<close> method is called or the IO::Uncompress::Unzip object is 1439destroyed. 1440 1441This parameter defaults to 0. 1442 1443=item C<< MultiStream => 0|1 >> 1444 1445Treats the complete zip file/buffer as a single compressed data 1446stream. When reading in multi-stream mode each member of the zip 1447file/buffer will be uncompressed in turn until the end of the file/buffer 1448is encountered. 1449 1450This parameter defaults to 0. 1451 1452=item C<< Prime => $string >> 1453 1454This option will uncompress the contents of C<$string> before processing the 1455input file/buffer. 1456 1457This option can be useful when the compressed data is embedded in another 1458file/data structure and it is not possible to work out where the compressed 1459data begins without having to read the first few bytes. If this is the 1460case, the uncompression can be I<primed> with these bytes using this 1461option. 1462 1463=item C<< Transparent => 0|1 >> 1464 1465If this option is set and the input file/buffer is not compressed data, 1466the module will allow reading of it anyway. 1467 1468In addition, if the input file/buffer does contain compressed data and 1469there is non-compressed data immediately following it, setting this option 1470will make this module treat the whole file/buffer as a single data stream. 1471 1472This option defaults to 1. 1473 1474=item C<< BlockSize => $num >> 1475 1476When reading the compressed input data, IO::Uncompress::Unzip will read it in 1477blocks of C<$num> bytes. 1478 1479This option defaults to 4096. 1480 1481=item C<< InputLength => $size >> 1482 1483When present this option will limit the number of compressed bytes read 1484from the input file/buffer to C<$size>. This option can be used in the 1485situation where there is useful data directly after the compressed data 1486stream and you know beforehand the exact length of the compressed data 1487stream. 1488 1489This option is mostly used when reading from a filehandle, in which case 1490the file pointer will be left pointing to the first byte directly after the 1491compressed data stream. 1492 1493This option defaults to off. 1494 1495=item C<< Append => 0|1 >> 1496 1497This option controls what the C<read> method does with uncompressed data. 1498 1499If set to 1, all uncompressed data will be appended to the output parameter 1500of the C<read> method. 1501 1502If set to 0, the contents of the output parameter of the C<read> method 1503will be overwritten by the uncompressed data. 1504 1505Defaults to 0. 1506 1507=item C<< Strict => 0|1 >> 1508 1509This option controls whether the extra checks defined below are used when 1510carrying out the decompression. When Strict is on, the extra tests are 1511carried out, when Strict is off they are not. 1512 1513The default for this option is off. 1514 1515=back 1516 1517=head2 Examples 1518 1519TODO 1520 1521=head1 Methods 1522 1523=head2 read 1524 1525Usage is 1526 1527 $status = $z->read($buffer) 1528 1529Reads a block of compressed data (the size of the compressed block is 1530determined by the C<Buffer> option in the constructor), uncompresses it and 1531writes any uncompressed data into C<$buffer>. If the C<Append> parameter is 1532set in the constructor, the uncompressed data will be appended to the 1533C<$buffer> parameter. Otherwise C<$buffer> will be overwritten. 1534 1535Returns the number of uncompressed bytes written to C<$buffer>, zero if eof 1536or a negative number on error. 1537 1538=head2 read 1539 1540Usage is 1541 1542 $status = $z->read($buffer, $length) 1543 $status = $z->read($buffer, $length, $offset) 1544 1545 $status = read($z, $buffer, $length) 1546 $status = read($z, $buffer, $length, $offset) 1547 1548Attempt to read C<$length> bytes of uncompressed data into C<$buffer>. 1549 1550The main difference between this form of the C<read> method and the 1551previous one, is that this one will attempt to return I<exactly> C<$length> 1552bytes. The only circumstances that this function will not is if end-of-file 1553or an IO error is encountered. 1554 1555Returns the number of uncompressed bytes written to C<$buffer>, zero if eof 1556or a negative number on error. 1557 1558=head2 getline 1559 1560Usage is 1561 1562 $line = $z->getline() 1563 $line = <$z> 1564 1565Reads a single line. 1566 1567This method fully supports the use of the variable C<$/> (or 1568C<$INPUT_RECORD_SEPARATOR> or C<$RS> when C<English> is in use) to 1569determine what constitutes an end of line. Paragraph mode, record mode and 1570file slurp mode are all supported. 1571 1572=head2 getc 1573 1574Usage is 1575 1576 $char = $z->getc() 1577 1578Read a single character. 1579 1580=head2 ungetc 1581 1582Usage is 1583 1584 $char = $z->ungetc($string) 1585 1586=head2 inflateSync 1587 1588Usage is 1589 1590 $status = $z->inflateSync() 1591 1592TODO 1593 1594=head2 getHeaderInfo 1595 1596Usage is 1597 1598 $hdr = $z->getHeaderInfo(); 1599 @hdrs = $z->getHeaderInfo(); 1600 1601This method returns either a hash reference (in scalar context) or a list 1602or hash references (in array context) that contains information about each 1603of the header fields in the compressed data stream(s). 1604 1605=head2 tell 1606 1607Usage is 1608 1609 $z->tell() 1610 tell $z 1611 1612Returns the uncompressed file offset. 1613 1614=head2 eof 1615 1616Usage is 1617 1618 $z->eof(); 1619 eof($z); 1620 1621Returns true if the end of the compressed input stream has been reached. 1622 1623=head2 seek 1624 1625 $z->seek($position, $whence); 1626 seek($z, $position, $whence); 1627 1628Provides a sub-set of the C<seek> functionality, with the restriction 1629that it is only legal to seek forward in the input file/buffer. 1630It is a fatal error to attempt to seek backward. 1631 1632Note that the implementation of C<seek> in this module does not provide 1633true random access to a compressed file/buffer. It works by uncompressing 1634data from the current offset in the file/buffer until it reaches the 1635uncompressed offset specified in the parameters to C<seek>. For very small 1636files this may be acceptable behaviour. For large files it may cause an 1637unacceptable delay. 1638 1639The C<$whence> parameter takes one the usual values, namely SEEK_SET, 1640SEEK_CUR or SEEK_END. 1641 1642Returns 1 on success, 0 on failure. 1643 1644=head2 binmode 1645 1646Usage is 1647 1648 $z->binmode 1649 binmode $z ; 1650 1651This is a noop provided for completeness. 1652 1653=head2 opened 1654 1655 $z->opened() 1656 1657Returns true if the object currently refers to a opened file/buffer. 1658 1659=head2 autoflush 1660 1661 my $prev = $z->autoflush() 1662 my $prev = $z->autoflush(EXPR) 1663 1664If the C<$z> object is associated with a file or a filehandle, this method 1665returns the current autoflush setting for the underlying filehandle. If 1666C<EXPR> is present, and is non-zero, it will enable flushing after every 1667write/print operation. 1668 1669If C<$z> is associated with a buffer, this method has no effect and always 1670returns C<undef>. 1671 1672B<Note> that the special variable C<$|> B<cannot> be used to set or 1673retrieve the autoflush setting. 1674 1675=head2 input_line_number 1676 1677 $z->input_line_number() 1678 $z->input_line_number(EXPR) 1679 1680Returns the current uncompressed line number. If C<EXPR> is present it has 1681the effect of setting the line number. Note that setting the line number 1682does not change the current position within the file/buffer being read. 1683 1684The contents of C<$/> are used to determine what constitutes a line 1685terminator. 1686 1687=head2 fileno 1688 1689 $z->fileno() 1690 fileno($z) 1691 1692If the C<$z> object is associated with a file or a filehandle, C<fileno> 1693will return the underlying file descriptor. Once the C<close> method is 1694called C<fileno> will return C<undef>. 1695 1696If the C<$z> object is associated with a buffer, this method will return 1697C<undef>. 1698 1699=head2 close 1700 1701 $z->close() ; 1702 close $z ; 1703 1704Closes the output file/buffer. 1705 1706For most versions of Perl this method will be automatically invoked if 1707the IO::Uncompress::Unzip object is destroyed (either explicitly or by the 1708variable with the reference to the object going out of scope). The 1709exceptions are Perl versions 5.005 through 5.00504 and 5.8.0. In 1710these cases, the C<close> method will be called automatically, but 1711not until global destruction of all live objects when the program is 1712terminating. 1713 1714Therefore, if you want your scripts to be able to run on all versions 1715of Perl, you should call C<close> explicitly and not rely on automatic 1716closing. 1717 1718Returns true on success, otherwise 0. 1719 1720If the C<AutoClose> option has been enabled when the IO::Uncompress::Unzip 1721object was created, and the object is associated with a file, the 1722underlying file will also be closed. 1723 1724=head2 nextStream 1725 1726Usage is 1727 1728 my $status = $z->nextStream(); 1729 1730Skips to the next compressed data stream in the input file/buffer. If a new 1731compressed data stream is found, the eof marker will be cleared and C<$.> 1732will be reset to 0. 1733 1734Returns 1 if a new stream was found, 0 if none was found, and -1 if an 1735error was encountered. 1736 1737=head2 trailingData 1738 1739Usage is 1740 1741 my $data = $z->trailingData(); 1742 1743Returns the data, if any, that is present immediately after the compressed 1744data stream once uncompression is complete. It only makes sense to call 1745this method once the end of the compressed data stream has been 1746encountered. 1747 1748This option can be used when there is useful information immediately 1749following the compressed data stream, and you don't know the length of the 1750compressed data stream. 1751 1752If the input is a buffer, C<trailingData> will return everything from the 1753end of the compressed data stream to the end of the buffer. 1754 1755If the input is a filehandle, C<trailingData> will return the data that is 1756left in the filehandle input buffer once the end of the compressed data 1757stream has been reached. You can then use the filehandle to read the rest 1758of the input file. 1759 1760Don't bother using C<trailingData> if the input is a filename. 1761 1762If you know the length of the compressed data stream before you start 1763uncompressing, you can avoid having to use C<trailingData> by setting the 1764C<InputLength> option in the constructor. 1765 1766=head1 Importing 1767 1768No symbolic constants are required by this IO::Uncompress::Unzip at present. 1769 1770=over 5 1771 1772=item :all 1773 1774Imports C<unzip> and C<$UnzipError>. 1775Same as doing this 1776 1777 use IO::Uncompress::Unzip qw(unzip $UnzipError) ; 1778 1779=back 1780 1781=head1 EXAMPLES 1782 1783=head2 Working with Net::FTP 1784 1785See L<IO::Compress::FAQ|IO::Compress::FAQ/"Compressed files and Net::FTP"> 1786 1787=head2 Walking through a zip file 1788 1789The code below can be used to traverse a zip file, one compressed data 1790stream at a time. 1791 1792 use IO::Uncompress::Unzip qw($UnzipError); 1793 1794 my $zipfile = "somefile.zip"; 1795 my $u = new IO::Uncompress::Unzip $zipfile 1796 or die "Cannot open $zipfile: $UnzipError"; 1797 1798 my $status; 1799 for ($status = 1; $status > 0; $status = $u->nextStream()) 1800 { 1801 1802 my $name = $u->getHeaderInfo()->{Name}; 1803 warn "Processing member $name\n" ; 1804 1805 my $buff; 1806 while (($status = $u->read($buff)) > 0) { 1807 # Do something here 1808 } 1809 1810 last if $status < 0; 1811 } 1812 1813 die "Error processing $zipfile: $!\n" 1814 if $status < 0 ; 1815 1816Each individual compressed data stream is read until the logical 1817end-of-file is reached. Then C<nextStream> is called. This will skip to the 1818start of the next compressed data stream and clear the end-of-file flag. 1819 1820It is also worth noting that C<nextStream> can be called at any time -- you 1821don't have to wait until you have exhausted a compressed data stream before 1822skipping to the next one. 1823 1824=head2 Unzipping a complete zip file to disk 1825 1826Daniel S. Sterling has written a script that uses C<IO::Uncompress::UnZip> 1827to read a zip file and unzip its contents to disk. 1828 1829The script is available from L<https://gist.github.com/eqhmcow/5389877> 1830 1831=head1 SEE ALSO 1832 1833L<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::Lzma>, L<IO::Uncompress::UnLzma>, L<IO::Compress::Xz>, L<IO::Uncompress::UnXz>, L<IO::Compress::Lzip>, L<IO::Uncompress::UnLzip>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Compress::Zstd>, L<IO::Uncompress::UnZstd>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress> 1834 1835L<IO::Compress::FAQ|IO::Compress::FAQ> 1836 1837L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>, 1838L<Archive::Tar|Archive::Tar>, 1839L<IO::Zlib|IO::Zlib> 1840 1841For RFC 1950, 1951 and 1952 see 1842L<http://www.faqs.org/rfcs/rfc1950.html>, 1843L<http://www.faqs.org/rfcs/rfc1951.html> and 1844L<http://www.faqs.org/rfcs/rfc1952.html> 1845 1846The I<zlib> compression library was written by Jean-loup Gailly 1847C<gzip@prep.ai.mit.edu> and Mark Adler C<madler@alumni.caltech.edu>. 1848 1849The primary site for the I<zlib> compression library is 1850L<http://www.zlib.org>. 1851 1852The primary site for gzip is L<http://www.gzip.org>. 1853 1854=head1 AUTHOR 1855 1856This module was written by Paul Marquess, C<pmqs@cpan.org>. 1857 1858=head1 MODIFICATION HISTORY 1859 1860See the Changes file. 1861 1862=head1 COPYRIGHT AND LICENSE 1863 1864Copyright (c) 2005-2019 Paul Marquess. All rights reserved. 1865 1866This program is free software; you can redistribute it and/or 1867modify it under the same terms as Perl itself. 1868 1869