diff options
author | Graham TerMarsch <graham@howlingfrog.com> | 2020-12-10 15:32:27 -0800 |
---|---|---|
committer | Graham TerMarsch <graham@howlingfrog.com> | 2020-12-10 15:32:27 -0800 |
commit | 1edd0b3b08e12547aafe74ce3b749dc2228632b6 (patch) | |
tree | 31fe4ce7b31be748aaee69c3d8a89df6f4f84cd0 /lib/Parse | |
parent | 247475ec41646a33d0bf0c3ff2e43d6e21ec80ff (diff) |
Avoid instantiating `Safe` compartment if operating in "unsafe" mode.
When operating in "unsafe" mode, the `$comp` never ends up getting used.
So, why even instantiate/initialize it if we know that we're not going
to be needing it?
This patch results from an examination of the time spent performing an
install of `Paws` (via `cpm`), and finding that a substantial amount of
overhead was involved in simply instantiating/initializing the `Safe`
compartment, even when `Parse::PMFile` was being used in `UNSAFE => 1`
mode.
While for many distributions, the overhead involved here would be
negligible, for `Paws` (with over 20k `.pm` files), the overhead becomes
substantial.
Rough timings with `cpm install --verbose Paws`...
Upstream:
16041 DONE resolve (0.477sec) Paws -> Paws-0.42 (from MetaDB)
16041 DONE fetch (19.435sec) Paws-0.42
16041 DONE configure (25.846sec) Paws-0.42
16041 DONE install (40.388sec) Paws-0.42
With Patch:
72651 DONE resolve (0.455sec) Paws -> Paws-0.42 (from MetaDB)
72651 DONE fetch (6.140sec) Paws-0.42
72651 DONE configure (4.488sec) Paws-0.42
72651 DONE install (41.798sec) Paws-0.42
Diffstat (limited to 'lib/Parse')
-rw-r--r-- | lib/Parse/PMFile.pm | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/lib/Parse/PMFile.pm b/lib/Parse/PMFile.pm index 3091b89..c6cc986 100644 --- a/lib/Parse/PMFile.pm +++ b/lib/Parse/PMFile.pm @@ -208,28 +208,31 @@ sub _parse_version { } else { # XXX Limit Resources too - my($comp) = Safe->new; + my $comp; my $eval = qq{ local(\$^W) = 0; Parse::PMFile::_parse_version_safely("$pmcp"); }; - $comp->permit("entereval"); # for MBARBON/Module-Info-0.30.tar.gz - $comp->share("*Parse::PMFile::_parse_version_safely"); - $comp->share("*version::new"); - $comp->share("*version::numify"); - $comp->share_from('main', ['*version::', - '*charstar::', - '*Exporter::', - '*DynaLoader::']); - $comp->share_from('version', ['&qv']); - $comp->permit(":base_math"); # atan2 (Acme-Pi) - # $comp->permit("require"); # no strict! - $comp->deny(qw/enteriter iter unstack goto/); # minimum protection against Acme::BadExample + unless ($self->{UNSAFE} || $UNSAFE) { + $comp = Safe->new; + $comp->permit("entereval"); # for MBARBON/Module-Info-0.30.tar.gz + $comp->share("*Parse::PMFile::_parse_version_safely"); + $comp->share("*version::new"); + $comp->share("*version::numify"); + $comp->share_from('main', ['*version::', + '*charstar::', + '*Exporter::', + '*DynaLoader::']); + $comp->share_from('version', ['&qv']); + $comp->permit(":base_math"); # atan2 (Acme-Pi) + # $comp->permit("require"); # no strict! + $comp->deny(qw/enteriter iter unstack goto/); # minimum protection against Acme::BadExample + } version->import('qv') if $self->{UNSAFE} || $UNSAFE; { no strict; - $v = ($self->{UNSAFE} || $UNSAFE) ? eval $eval : $comp->reval($eval); + $v = $comp ? $comp->reval($eval) : eval $eval; } if ($@){ # still in the child process, out of Safe::reval my $err = $@; @@ -239,7 +242,7 @@ sub _parse_version { local($^W) = 0; my ($sigil, $vstr) = ($1, $3); $self->_restore_overloaded_stuff(1) if $err->{line} =~ /use\s+version\b|version\->|qv\(/; - $v = ($self->{UNSAFE} || $UNSAFE) ? eval $vstr : $comp->reval($vstr); + $v = $comp ? $comp->reval($vstr) : eval $vstr; $v = $$v if $sigil eq '*' && ref $v; } if ($@ or !$v) { @@ -267,7 +270,7 @@ sub _parse_version { utf8::encode($v); # undefine empty $v as if read from the tmpfile $v = undef if defined $v && !length $v; - $comp->erase; + $comp->erase if ($comp); $self->_restore_overloaded_stuff; } } |