RE: Perl @ 33218 (Stratus VOS patches)
[p5sagit/p5-mst-13.2.git] / ext / Opcode / Safe.pm
index b090e40..04a3b55 100644 (file)
@@ -3,9 +3,32 @@ package Safe;
 use 5.003_11;
 use strict;
 
-$Safe::VERSION = "2.09";
+$Safe::VERSION = "2.15";
+
+# *** Don't declare any lexicals above this point ***
+#
+# This function should return a closure which contains an eval that can't
+# see any lexicals in scope (apart from __ExPr__ which is unavoidable)
+
+sub lexless_anon_sub {
+                # $_[0] is package;
+                # $_[1] is strict flag;
+    my $__ExPr__ = $_[2];   # must be a lexical to create the closure that
+                           # can be used to pass the value into the safe
+                           # world
+
+    # Create anon sub ref in root of compartment.
+    # Uses a closure (on $__ExPr__) to pass in the code to be executed.
+    # (eval on one line to keep line numbers as expected by caller)
+    eval sprintf
+    'package %s; %s strict; sub { @_=(); eval q[my $__ExPr__;] . $__ExPr__; }',
+               $_[0], $_[1] ? 'use' : 'no';
+}
 
 use Carp;
+BEGIN { eval q{
+    use Carp::Heavy;
+} }
 
 use Opcode 1.01, qw(
     opset opset_to_ops opmask_add
@@ -17,7 +40,61 @@ use Opcode 1.01, qw(
 
 
 my $default_root  = 0;
-my $default_share = ['*_']; #, '*main::'];
+# share *_ and functions defined in universal.c
+# Don't share stuff like *UNIVERSAL:: otherwise code from the
+# compartment can 0wn functions in UNIVERSAL
+my $default_share = [qw[
+    *_
+    &PerlIO::get_layers
+    &Regexp::DESTROY
+    &UNIVERSAL::isa
+    &UNIVERSAL::can
+    &UNIVERSAL::VERSION
+    &utf8::is_utf8
+    &utf8::valid
+    &utf8::encode
+    &utf8::decode
+    &utf8::upgrade
+    &utf8::downgrade
+    &utf8::native_to_unicode
+    &utf8::unicode_to_native
+    $version::VERSION
+    $version::CLASS
+    @version::ISA
+], ($] >= 5.010 && qw[
+    &re::is_regexp
+    &re::regname
+    &re::regnames
+    &re::regnames_count
+    &Tie::Hash::NamedCapture::FETCH
+    &Tie::Hash::NamedCapture::STORE
+    &Tie::Hash::NamedCapture::DELETE
+    &Tie::Hash::NamedCapture::CLEAR
+    &Tie::Hash::NamedCapture::EXISTS
+    &Tie::Hash::NamedCapture::FIRSTKEY
+    &Tie::Hash::NamedCapture::NEXTKEY
+    &Tie::Hash::NamedCapture::SCALAR
+    &Tie::Hash::NamedCapture::flags
+    &UNIVERSAL::DOES
+    &version::()
+    &version::new
+    &version::(""
+    &version::stringify
+    &version::(0+
+    &version::numify
+    &version::normal
+    &version::(cmp
+    &version::(<=>
+    &version::vcmp
+    &version::(bool
+    &version::boolean
+    &version::(nomethod
+    &version::noop
+    &version::is_alpha
+    &version::qv
+]), ($] >= 5.011 && qw[
+    &re::regexp_pattern
+])];
 
 sub new {
     my($class, $root, $mask) = @_;
@@ -162,9 +239,6 @@ sub share_from {
     my $arg;
     foreach $arg (@$vars) {
        # catch some $safe->share($var) errors:
-       croak("'$arg' not a valid symbol table name")
-           unless $arg =~ /^[\$\@%*&]?\w[\w:]*$/
-               or $arg =~ /^\$\W$/;
        my ($var, $type);
        $type = $1 if ($var = $arg) =~ s/^(\W)//;
        # warn "share_from $pkg $type $var";
@@ -211,15 +285,7 @@ sub reval {
     my ($obj, $expr, $strict) = @_;
     my $root = $obj->{Root};
 
-    # Create anon sub ref in root of compartment.
-    # Uses a closure (on $expr) to pass in the code to be executed.
-    # (eval on one line to keep line numbers as expected by caller)
-    my $evalcode = sprintf('package %s; sub { @_ = (); eval $expr; }', $root);
-    my $evalsub;
-
-    if ($strict) { use strict; $evalsub = eval $evalcode; }
-    else         {  no strict; $evalsub = eval $evalcode; }
-
+    my $evalsub = lexless_anon_sub($root,$strict, $expr);
     return Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub);
 }
 
@@ -291,7 +357,7 @@ compilation to fail with an error. The code will not be executed.
 The default operator mask for a newly created compartment is
 the ':default' optag.
 
-It is important that you read the Opcode(3) module documentation
+It is important that you read the L<Opcode> module documentation
 for more information, especially for detailed definitions of opnames,
 optags and opsets.
 
@@ -355,6 +421,9 @@ is implicit in each case.
 Permit the listed operators to be used when compiling code in the
 compartment (in I<addition> to any operators already permitted).
 
+You can list opcodes by names, or use a tag name; see
+L<Opcode/"Predefined Opcode Tags">.
+
 =item permit_only (OP, ...)
 
 Permit I<only> the listed operators to be used when compiling code in
@@ -550,11 +619,11 @@ but more subtle effect.
 
 =head2 AUTHOR
 
-Originally designed and implemented by Malcolm Beattie,
-mbeattie@sable.ox.ac.uk.
+Originally designed and implemented by Malcolm Beattie.
+
+Reworked to use the Opcode module and other changes added by Tim Bunce.
 
-Reworked to use the Opcode module and other changes added by Tim Bunce
-E<lt>F<Tim.Bunce@ig.co.uk>E<gt>.
+Currently maintained by the Perl 5 Porters, <perl5-porters@perl.org>.
 
 =cut