#!/usr/bin/perl -w
use strict;
use Opcode qw(opset opmask_add opset_to_ops invert_opset);
my $code = shift;
defined $code or
die "Usage: $0 ...\n";
# skip some masks from prev operations
my %skip;
$skip{$_}++ for @ARGV;
my @all = opset_to_ops(invert_opset(opset()));
# Try all opcodes, print error if eval failed
foreach ( @all ) {
$skip{$_} and next;
opmask_add(opset($_));
eval $code and next;
print "Eval failed on opcode: $_ with error: $@\n";
exit 1;
};
print "Eval OK\n";
##
##
#!/usr/bin/perl -w
use strict;
use warnings;
use 5.012;
use Safe;
use Carp;
my $code = shift;
die "Usage: $0 ..." unless defined $code;
my @perm = @ARGV;
print "Trying: $code\n";
my $compartment = Safe->new;
$compartment->share('*STDIN');
$compartment->share('&Dumper');
$compartment->permit_only(@perm);
# Trap detailed stack trace
my $stack;
local $SIG{__DIE__} = sub { $stack = Carp::longmess(shift) };
print $compartment->reval($code);
if ($@) {
print "Unsafe code detected: $@";
print "At: $stack";
}
##
##
bash$ perl safe2.pl 1
Trying: 1
Unsafe code detected: 'private value' trapped by operation mask at (eval 5) line 1.
At: 'private value' trapped by operation mask at (eval 5) line 1.
at (eval 5) line 1
eval 'my $__ExPr__;1
;' called at (eval 4) line 1
main::__ANON__(** Incomplete caller override detected; @DB::args were not set **) called at /usr/share/perl/5.14/Safe.pm line 358
eval {...} called at /usr/share/perl/5.14/Safe.pm line 358
Safe::reval(** Incomplete caller override detected; @DB::args were not set **) called at safe2.pl line 26
##
##
bash$ perl safe2.pl 1 padany const leaveeval lineseq
Trying: 1
1