Skip Menu |

This queue is for tickets about the Archive-Extract CPAN distribution.

Report information
The Basics
Id: 47053
Status: resolved
Priority: 0/
Queue: Archive-Extract

People
Owner: Nobody in particular
Requestors: DOUGDUDE [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: (no value)



Subject: Use Archive::Tar iter to keep from read the tar into memory
Archive::Tar implements a streaming reader in version 1.40+ that enables the archive to be extracted without reading the entire archive into memory. An example patch is included for use against Archive-Extract-0.32
Subject: Extract.patch
--- lib/Archive/Extract.pm Wed Jun 17 12:38:19 2009 +++ lib/Archive/Extract.pm Wed Jun 17 12:58:18 2009 @@ -786,15 +786,6 @@ ### localized $Archive::Tar::WARN already. $Archive::Tar::WARN = $Archive::Extract::WARN; - my $tar = Archive::Tar->new(); - - ### only tell it it's compressed if it's a .tgz, as we give it a file - ### handle if it's a .tbz - unless( $tar->read( $fh_to_read, ( $self->is_tgz ? 1 : 0 ) ) ) { - return $self->_error(loc("Unable to read '%1': %2", $self->archive, - $Archive::Tar::error)); - } - ### workaround to prevent Archive::Tar from setting uid, which ### is a potential security hole. -autrijus ### have to do it here, since A::T needs to be /loaded/ first ### @@ -807,17 +798,50 @@ ### for version of Archive::Tar > 1.04 local $Archive::Tar::CHOWN = 0; - { local $^W; # quell 'splice() offset past end of array' warnings - # on older versions of A::T + my @files; + + if (eval 'my $v = Archive::Tar->VERSION; defined $v && $v > 1.40;') { + ### unroll the tar using the iterator interface as not to load + ### the entire tarball into memory + my $next = Archive::Tar->iter( $fh_to_read, ( $self->is_tgz ? 1 : 0 ) ); + + if ( !defined $next ) { + return $self->_error(loc("Unable to read '%1': %2", $self->archive, + $Archive::Tar::error)); + } + + ### extract the tarball + while ( my $file = $next->() ) { + push @files, $file->full_path; + + $file->extract() + or return $self->_error(loc("Unable to extract '%1': %2", + $self->archive, $Archive::Tar::error )); + } + } + else { + my $tar = Archive::Tar->new(); + + ### only tell it it's compressed if it's a .tgz, as we give it a file + ### handle if it's a .tbz + unless( $tar->read( $fh_to_read, ( $self->is_tgz ? 1 : 0 ) ) ) { + return $self->_error(loc("Unable to read '%1': %2", $self->archive, + $Archive::Tar::error)); + } + + { local $^W; # quell 'splice() offset past end of array' warnings + # on older versions of A::T + + ### older archive::tar always returns $self, return value slightly + ### fux0r3d because of it. + $tar->extract() + or return $self->_error(loc("Unable to extract '%1': %2", + $self->archive, $Archive::Tar::error )); + } - ### older archive::tar always returns $self, return value slightly - ### fux0r3d because of it. - $tar->extract() - or return $self->_error(loc("Unable to extract '%1': %2", - $self->archive, $Archive::Tar::error )); + @files = $tar->list_files; } - my @files = $tar->list_files; my $dir = $self->__get_extract_dir( \@files ); ### store the files that are in the archive ###
On Wed Jun 17 12:54:42 2009, DOUGDUDE wrote: Show quoted text
> Archive::Tar implements a streaming reader in version 1.40+ that enables > the archive to be extracted without reading the entire archive into > memory. An example patch is included for use against Archive-Extract-0.32
Thanks for the patch; issue addressed in SVN and release forthcoming.