Archive-Tar
view release on metacpan or search on metacpan
lib/Archive/Tar.pm view on Meta::CPAN
# straight from the tarball
if( not defined $alt and
not $INSECURE_EXTRACT_MODE
) {
### paths that leave the current directory are not allowed under
### strict mode, so only allow it if a user tells us to do this.
if( grep { $_ eq '..' } @dirs ) {
$self->_error(
q[Entry ']. $entry->full_path .q[' is attempting to leave ].
q[the current working directory. Not extracting under ].
q[SECURE EXTRACT MODE]
);
return;
}
### the archive may be asking us to extract into a symlink. This
### is not sane and a possible security issue, as outlined here:
### https://rt.cpan.org/Ticket/Display.html?id=30380
### https://bugzilla.redhat.com/show_bug.cgi?id=295021
### https://issues.rpath.com/browse/RPL-1716
my $full_path = $cwd;
for my $d ( @dirs ) {
$full_path = File::Spec->catdir( $full_path, $d );
### we've already checked this one, and it's safe. Move on.
next if ref $self and $self->{_link_cache}->{$full_path};
if( -l $full_path ) {
my $to = readlink $full_path;
my $diag = "symlinked directory ($full_path => $to)";
$self->_error(
q[Entry ']. $entry->full_path .q[' is attempting to ].
qq[extract to a $diag. This is considered a security ].
q[vulnerability and not allowed under SECURE EXTRACT ].
q[MODE]
);
return;
}
### XXX keep a cache if possible, so the stats become cheaper:
$self->{_link_cache}->{$full_path} = 1 if ref $self;
}
}
### '.' is the directory delimiter on VMS, which has to be escaped
### or changed to '_' on vms. vmsify is used, because older versions
### of vmspath do not handle this properly.
### Must not add a '/' to an empty directory though.
map { length() ? VMS::Filespec::vmsify($_.'/') : $_ } @dirs if ON_VMS;
my ($cwd_vol,$cwd_dir,$cwd_file)
= File::Spec->splitpath( $cwd );
my @cwd = File::Spec->splitdir( $cwd_dir );
push @cwd, $cwd_file if length $cwd_file;
### We need to pass '' as the last element to catpath. Craig Berry
### explains why (msgid <p0624083dc311ae541393@[172.16.52.1]>):
### The root problem is that splitpath on UNIX always returns the
### final path element as a file even if it is a directory, and of
### course there is no way it can know the difference without checking
### against the filesystem, which it is documented as not doing. When
### you turn around and call catpath, on VMS you have to know which bits
### are directory bits and which bits are file bits. In this case we
### know the result should be a directory. I had thought you could omit
### the file argument to catpath in such a case, but apparently on UNIX
### you can't.
$dir = File::Spec->catpath(
$cwd_vol, File::Spec->catdir( @cwd, @dirs ), ''
);
### catdir() returns undef if the path is longer than 255 chars on
### older VMS systems.
unless ( defined $dir ) {
$^W && $self->_error( qq[Could not compose a path for '$dirs'\n] );
return;
}
}
if( -e $dir && !-d _ ) {
$^W && $self->_error( qq['$dir' exists, but it's not a directory!\n] );
return;
}
unless ( -d _ ) {
eval { File::Path::mkpath( $dir, 0, 0777 ) };
if( $@ ) {
my $fp = $entry->full_path;
$self->_error(qq[Could not create directory '$dir' for '$fp': $@]);
return;
}
### XXX chown here? that might not be the same as in the archive
### as we're only chown'ing to the owner of the file we're extracting
### not to the owner of the directory itself, which may or may not
### be another entry in the archive
### Answer: no, gnu tar doesn't do it either, it'd be the wrong
### way to go.
#if( $CHOWN && CAN_CHOWN ) {
# chown $entry->uid, $entry->gid, $dir or
# $self->_error( qq[Could not set uid/gid on '$dir'] );
#}
}
### we're done if we just needed to create a dir ###
return 1 if $entry->is_dir;
my $full = File::Spec->catfile( $dir, $file );
if( $entry->is_unknown ) {
$self->_error( qq[Unknown file type for file '$full'] );
return;
}
### If a file system already contains a block device with the same name as
### the being extracted regular file, we would write the file's content
### to the block device. So remove the existing file (block device) now.
( run in 1.523 second using v1.01-cache-2.11-cpan-d8267643d1d )