Skip to content

Commit

Permalink
Item15192: use a Safe for $EVAL()
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelDaum committed May 23, 2023
1 parent a0bc7a1 commit 0714f19
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 26 deletions.
19 changes: 11 additions & 8 deletions SpreadSheetPlugin/lib/Foswiki/Plugins/SpreadSheetPlugin/Calc.pm
Expand Up @@ -13,6 +13,7 @@ use warnings;
use HTML::Entities;
use Time::Local;
use Time::Local qw( timegm_nocheck timelocal_nocheck ); # Necessary for DOY
use Safe ();

# =========================
my $web;
Expand All @@ -29,6 +30,7 @@ my $escCloseP = "\3";
my $escNewLn = "\4";
my %varStore = ();
my $dontSpaceRE = "";
my $safeCpt;

# SMELL: I18N
my @monArr = (
Expand Down Expand Up @@ -1722,8 +1724,14 @@ sub _getNumber {
# =========================
sub _safeEvalPerl {
my ($theText) = @_;

$theText = '' unless defined $theText;

unless ( defined $safeCpt ) {
$safeCpt = Safe->new();
$safeCpt->deny(":subprocess");
}

# Allow only simple math with operators - + * / % ( )
$theText =~ s/\%\s*[^\-\+\*\/0-9\.\(\)]+//g; # defuse %hash but keep modulus

Expand All @@ -1740,16 +1748,10 @@ sub _safeEvalPerl {
$theText =~ /(.*)/;
$theText = $1;

# disable glob for security reasons
while ( $theText =~ s/\<[\.\*\/\?\se\<]*\>/ /g ) {
1;
}

return "" unless defined($theText);

local $SIG{__DIE__} =
sub { Foswiki::Func::writeDebug( $_[0] ); warn $_[0] };
my $result = eval $theText;
local $SIG{__DIE__} = sub { warn $_[0] };
my $result = $safeCpt->reval($theText);

if ($@) {
$result = $@;
Expand All @@ -1764,6 +1766,7 @@ sub _safeEvalPerl {
else {
$result = 0 unless ($result); # logical false is "0"
}

return $result;
}

Expand Down
Expand Up @@ -438,24 +438,12 @@ sub test_EVAL_GLOB {
my ($this) = @_;

$this->assert( $this->CALC('$EVAL(1 < 2 + 2 > 1)') == 1 );
$this->assert( $this->CALC('$EVAL(1 <2 <> )') == 1 );
$this->assert( $this->CALC('$EVAL(<>)') == 0 );
$this->assert( $this->CALC('$EVAL(<<>>)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(<<<>>>)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(<*>)') == 0 );
$this->assert( $this->CALC('$EVAL((<*>))') == 0 );
$this->assert( $this->CALC('$EVAL(< * >)') == 0 );
$this->assert( $this->CALC('$EVAL(<../../../ee*/* >)') == 0 );
$this->assert( $this->CALC('$EVAL(2+<>+2)') == 4 );
$this->assert( $this->CALC('$EVAL(2+< >+2)') == 4 );
$this->assert( $this->CALC('$EVAL(%+.<*>.2)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(2+<e>+2)') == 4 );
$this->assert( $this->CALC('$EVAL(2+<x>+2)') == 4 );
$this->assert( $this->CALC('$EVAL(%-.<*>.2)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(%+.<../*>.2)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(3-<../*>-3)') == 6 );
$this->assert( $this->CALC('$EVAL(%-.<ee*/..>.%-)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(%-.<<>../*>.%-)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(1 <2 <> )') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(<>)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(<<>>)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(<<<>>>)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL(<*>)') =~ /^ERROR:/ );
$this->assert( $this->CALC('$EVAL((<*>))') =~ /^ERROR:/ );
}

sub test_EVEN {
Expand Down

0 comments on commit 0714f19

Please sign in to comment.