From 54dc0ee714bb947eed00373466acf75942b4b150 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Tue, 22 Aug 2023 17:56:18 -0500 Subject: [PATCH] Protect EV3P command output from variable substitution. This an alternate to #917 (and #914) to fix issue #912. This uses the technique described by @dpvc in https://github.com/openwebwork/pg/pull/914#issuecomment-1688929625 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. --- macros/core/PGbasicmacros.pl | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/macros/core/PGbasicmacros.pl b/macros/core/PGbasicmacros.pl index bd6368a50f..bd5e3ae807 100644 --- a/macros/core/PGbasicmacros.pl +++ b/macros/core/PGbasicmacros.pl @@ -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); @@ -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("<