| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# This is an implementation of Eval::Safe that uses `eval` to execute the user |
|
2
|
|
|
|
|
|
|
# provided code. |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package Eval::Safe::Eval; |
|
5
|
|
|
|
|
|
|
|
|
6
|
3
|
|
|
3
|
|
39
|
use 5.022; |
|
|
3
|
|
|
|
|
10
|
|
|
7
|
3
|
|
|
3
|
|
12
|
use strict; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
46
|
|
|
8
|
3
|
|
|
3
|
|
10
|
use warnings; |
|
|
3
|
|
|
|
|
4
|
|
|
|
3
|
|
|
|
|
251
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
3
|
|
|
3
|
|
1093
|
use parent 'Eval::Safe'; |
|
|
3
|
|
|
|
|
828
|
|
|
|
3
|
|
|
|
|
14
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
3
|
|
|
3
|
|
145
|
use Carp; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
132
|
|
|
13
|
3
|
|
|
3
|
|
1304
|
use File::Spec::Functions qw(rel2abs); |
|
|
3
|
|
|
|
|
2321
|
|
|
|
3
|
|
|
|
|
1456
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# Count the number of Eval::Safe::Eval object created to assign each of them a |
|
16
|
|
|
|
|
|
|
# specific package name. |
|
17
|
|
|
|
|
|
|
my $env_count = 0; |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub new { |
|
20
|
2
|
|
|
2
|
1
|
8
|
my ($class, %options) = @_; |
|
21
|
2
|
|
|
|
|
5
|
my $self = bless \%options, $class; |
|
22
|
2
|
50
|
|
|
|
11
|
$self->{package} = 'Eval::Safe::Eval::Env'.($env_count++) unless $self->{package}; |
|
23
|
2
|
|
|
|
|
10
|
return $self; |
|
24
|
|
|
|
|
|
|
} |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub DESTROY { |
|
27
|
2
|
|
|
2
|
|
1079
|
local($., $@, $!, $^E, $?); |
|
28
|
2
|
|
|
|
|
4
|
my ($this) = @_; |
|
29
|
2
|
|
|
|
|
94
|
CORE::eval('undef %'.($this->{package}).'::'); |
|
30
|
|
|
|
|
|
|
} |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub eval { |
|
33
|
0
|
|
|
0
|
1
|
|
my ($this, $code) = @_; |
|
34
|
|
|
|
|
|
|
my $eval_str = sprintf "package %s; %s; %s; %s", $this->{package}, |
|
35
|
0
|
|
|
|
|
|
$this->{strict}, $this->{warnings}, $code; |
|
36
|
0
|
0
|
|
|
|
|
print {$this->{debug}} "Evaling (eval): '${eval_str}'\n" if $this->{debug}; |
|
|
0
|
|
|
|
|
|
|
|
37
|
0
|
|
|
|
|
|
my @ret; |
|
38
|
0
|
0
|
|
|
|
|
if (not defined wantarray) { |
|
|
|
0
|
|
|
|
|
|
|
39
|
0
|
|
|
|
|
|
CORE::eval($eval_str); |
|
40
|
|
|
|
|
|
|
} elsif (wantarray) { |
|
41
|
0
|
|
|
|
|
|
@ret = CORE::eval($eval_str); |
|
42
|
|
|
|
|
|
|
} else { |
|
43
|
0
|
|
|
|
|
|
@ret = scalar CORE::eval($eval_str); |
|
44
|
|
|
|
|
|
|
} |
|
45
|
0
|
0
|
0
|
|
|
|
print {$this->{debug}} "Eval returned an error: $@" if $this->{debug} && $@; |
|
|
0
|
|
|
|
|
|
|
|
46
|
0
|
|
|
|
|
|
return $this->_wrap_code_refs(\&_wrap_in_eval, @ret); |
|
47
|
|
|
|
|
|
|
} |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub do { |
|
50
|
0
|
|
|
0
|
1
|
|
my ($this, $file) = @_; |
|
51
|
|
|
|
|
|
|
# do can open relative paths, but in that case it looks them up in the @INC |
|
52
|
|
|
|
|
|
|
# directory, which we want to avoid. |
|
53
|
|
|
|
|
|
|
# We don't use abs_path here to not die (just yet) if the file does not exist. |
|
54
|
0
|
|
|
|
|
|
my $abs_path = rel2abs($file); |
|
55
|
0
|
|
|
|
|
|
$this->eval("my \$r = do '${abs_path}'; die \$@ if \$@; \$r"); |
|
56
|
|
|
|
|
|
|
} |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
# To emulate the behavior of the Safe approach (where code returned by eval is |
|
59
|
|
|
|
|
|
|
# wrapped to trap all exception, we're using this method to wrap code returned |
|
60
|
|
|
|
|
|
|
# by eval in the same way). |
|
61
|
|
|
|
|
|
|
sub _wrap_in_eval { |
|
62
|
0
|
|
|
0
|
|
|
my ($this, $sub) = @_; |
|
63
|
|
|
|
|
|
|
# When $sub is called, we're executing it in an `eval` and also wrapping all |
|
64
|
|
|
|
|
|
|
# its returned code in the same way. |
|
65
|
|
|
|
|
|
|
return sub { |
|
66
|
0
|
|
|
0
|
|
|
my @ret; |
|
67
|
0
|
0
|
|
|
|
|
if (not defined wantarray) { |
|
|
|
0
|
|
|
|
|
|
|
68
|
0
|
|
|
|
|
|
eval { $sub->() }; |
|
|
0
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
} elsif (wantarray) { |
|
70
|
0
|
|
|
|
|
|
@ret = eval { $sub->() }; |
|
|
0
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
} else { |
|
72
|
0
|
|
|
|
|
|
@ret = scalar eval { $sub->() }; |
|
|
0
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
} |
|
74
|
0
|
|
|
|
|
|
$this->_wrap_code_refs(\&_wrap_in_eval, @ret) |
|
75
|
0
|
|
|
|
|
|
}; |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
1; |