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 Oct 1, 2023
1 parent 0523d4f commit 54dc0ee
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 54dc0ee

Please sign in to comment.