File Coverage

blib/lib/Eval/Safe/Safe.pm
Criterion Covered Total %
statement 32 51 62.7
branch 2 16 12.5
condition 0 3 0.0
subroutine 9 11 81.8
pod 3 3 100.0
total 46 84 54.7


line stmt bran cond sub pod time code
1             # This is an implementation of Eval::Safe that uses the Safe module to execute
2             # the user provided code.
3              
4             package Eval::Safe::Safe;
5              
6 3     3   44 use 5.022;
  3         9  
7 3     3   13 use strict;
  3         4  
  3         48  
8 3     3   11 use warnings;
  3         4  
  3         96  
9              
10 3     3   14 use parent 'Eval::Safe';
  3         4  
  3         11  
11              
12 3     3   192 use Carp;
  3         6  
  3         121  
13 3     3   1548 use Eval::Safe::ForkedSafe;
  3         9  
  3         147  
14 3     3   25 use File::Spec::Functions qw(rel2abs);
  3         5  
  3         1137  
15              
16             sub new {
17 1     1 1 3 my ($class, %options) = @_;
18 1         3 my $self = bless \%options, $class;
19 1         10 my $safe = Eval::Safe::ForkedSafe->new($self->{package});
20 1 50       6 $self->{package} = $safe->root() unless $self->{package};
21             # This option is always set if we're building an Eval::Safe::Safe.
22 1 50       4 if ($self->{safe} > 1) {
23 0         0 $safe->permit_only(qw(:base_core :base_mem :base_loop :base_math :base_orig
24             :load));
25 0         0 $safe->deny(qw(tie untie bless));
26             } else {
27 1         8 $safe->deny_only(qw(:subprocess :ownprocess :others :dangerous));
28             }
29 1         2 $self->{safe} = $safe;
30 1         5 return $self;
31             }
32              
33              
34             sub DESTROY {
35 1     1   535 local($., $@, $!, $^E, $?);
36 1         2 my ($this) = @_;
37 1         5 delete $this->{safe};
38             # The package is not entirely deleted by the Safe destructor.
39 1         51 CORE::eval('undef %'.($this->{package}).'::');
40             }
41              
42              
43             sub eval {
44 0     0 1   my ($this, $code) = @_;
45 0           my $eval_str = sprintf "%s; %s; %s", $this->{strict}, $this->{warnings}, $code;
46 0 0         print {$this->{debug}} "Evaling (safe): '${eval_str}'\n" if $this->{debug};
  0            
47 0           my @ret;
48 0 0         if (not defined wantarray) {
    0          
49 0           $this->{safe}->reval($eval_str);
50             } elsif (wantarray) {
51 0           @ret = $this->{safe}->reval($eval_str);
52             } else {
53 0           @ret = scalar $this->{safe}->reval($eval_str);
54             }
55 0 0 0       print {$this->{debug}} "Safe returned an error: $@" if $this->{debug} && $@;
  0            
56 0 0         if (defined wantarray) {
57 0 0         return (wantarray) ? @ret : $ret[0];
58             }
59 0           return;
60             }
61              
62             sub do {
63 0     0 1   my ($this, $file) = @_;
64             # do can open relative paths, but in that case it looks them up in the @INC
65             # directory, which we want to avoid.
66             # We don't use abs_path here to not die (just yet) if the file does not exist.
67 0           my $abs_path = rel2abs($file);
68 0           $this->{safe}->rdo($abs_path);
69             }
70              
71             1;