Skip to content

Commit

Permalink
Protect EV3P command output from variable substitution.
Browse files Browse the repository at this point in the history
This an alternate to #917 (and #914) to fix issue #912.  This uses the
technique described by @dpvc in
#914 (comment) with
a minor tweak to limit the scope of `$__blank__`.

Here is a MWE with all of the issues that have been brought up:
```perl
DOCUMENT();

loadMacros('PGstandard.pl', 'MathObjects.pl');

$x = "one"; $xx = "two"; $xxx = "three";
$y = '$x';

BEGIN_TEXT
$DOLLAR\{ ans_rule(1) \}
$PAR
$x\{"x"\} and $x\{"x"\}x and \{$y\}x
END_TEXT

ANS(Real(1)->cmp);

ENDDOCUMENT();
```

With the develop branch the above example will work in html, but the
output on the second line will be "two and three and two".  With this
pull request the output on the  second line will be
"onex and onexx and onex".

With the develop branch the above example will not work in hardcopy, but
with this branch it will.
  • Loading branch information
drgrice1 committed Sep 11, 2023
1 parent fc2bb90 commit 73e7db8
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions macros/core/PGbasicmacros.pl
Original file line number Diff line number Diff line change
Expand Up @@ -2070,6 +2070,12 @@ sub safe_ev {
($out, $PG_eval_errors, $PG_full_error_report);
}

sub safe_evp {
my @result = &safe_ev;
$result[0] = '${__blank__}' . $result[0] . '${__blank__}';
return @result;
}

sub old_safe_ev {
my $in = shift;
my ($out, $PG_eval_errors, $PG_full_error_report) = PG_restricted_eval($in);
Expand Down Expand Up @@ -2289,12 +2295,13 @@ sub EV3P {
%{$option_ref},
);
my $string = join(" ", @_);
$string = ev_substring($string, "\\\\{", "\\\\}", \&safe_ev) if $options{processCommands};
$string = ev_substring($string, "\\\\{", "\\\\}", $options{processVariables} ? \&safe_evp : \&safe_ev)
if $options{processCommands};
if ($options{processVariables}) {
my $eval_string = $string;
$eval_string =~ s/\$(?![a-z\{])/\${DOLLAR}/gi if $options{fixDollars};
my ($evaluated_string, $PG_eval_errors, $PG_full_errors) =
PG_restricted_eval("<<END_OF_EVALUATION_STRING\n$eval_string\nEND_OF_EVALUATION_STRING\n");
my ($evaluated_string, $PG_eval_errors, $PG_full_errors) = PG_restricted_eval(
q{my $__blank__ = '';} . "<<END_OF_EVALUATION_STRING\n$eval_string\nEND_OF_EVALUATION_STRING\n");
if ($PG_eval_errors) {
my $error = (split("\n", $PG_eval_errors))[0];
$error =~ s/at \(eval.*//gs;
Expand Down

0 comments on commit 73e7db8

Please sign in to comment.