I am writing a Perl script where the user can input a regex and a replacement string. The script will search a set of files and apply changes according the perl s///
operator applied with the user input.
To complicate matters slightly, the replacement string is allowed to contain backreferences to refer to capture groups in the regex. For example, if the regex is b(.*?)a
and the replacement string is a$1b
the $1
should not be treated literally, but rater as a backreference to capture group number one.
In this setting, I am wondering if it is possible to use the ee
modifier (to evaluate the backreferences in the user input) safely with the s///
operator when the right hand side of this operator is input by the user? For example:
use strict;
use warnings;
my $str = 'abaaca';
my $replacement = 'do{ use Env qw(HOME); unlink "$HOME/important.txt" }';
$str =~ s/a(.*?)a/$replacement/gee;
would be unfortunate.. But then I got the idea to quote the user input (put it inside a pair of double quotes) after having escaped double quotes and dollar signs (not followed by a number), and then do replacement:
use feature qw(say);
use strict;
use warnings;
my $str = 'abaaca';
my $replacement = shift;
$replacement =~ s/\"/\\\"/g;
$replacement =~ s/\$(?!\d)/\\\$/g;
$replacement = '"' . $replacement . '"';
$str =~ s/a(.*?)a/$replacement/gee;
say $str;
To me this seems to work at first glance, or have I missed something?
For example if the script is called test.pl
and the user runs it as:
$ test.pl 'do{ "a$b" }'
the output is as desired just a simple string ( and no code is evaluated ):
do{ "a$b" }do{ "a$b" }
So the question is: Is this really a safe/correct approach?
The modifiers are EA: ESA, anemia, chemo-induced; EB: ESA, anemia, radio-induced; and EC: ESA, anemia, non-chemo/radio. I'm sure that you've seen that you now have to report the HgB or HCT as well.
The modifiers are EA: ESA, anemia, chemo-induced; EB: ESA, anemia, radio-induced; and EC: ESA, anemia, non-chemo/radio. I'm sure that you've seen that you now have to report the HgB or HCT as well. You continue to use the EJ modifier to report subsequent administrations of ESAs.
Solved: Right side of the equal operator must be a constan... - Power Platform Community 12-13-2021 11:14 AM I'm trying to patch a CDS entity with data that must be looked up in another CDS entity. Patching with a LookUp within a ForAll.
Why not use the #..# operator instead of that long sequence of numbers. Good point! Confused? Here’s the deal: This operator doesn’t play nicely with most other operators. Nor does it seem to work a lot of the time anyway—it’s definitely hit and miss. So I recommend using a sequence of numbers separated by “ OR ” or the pipe (“|”) operator.
Problem 1:
There's no way to replace with $1
followed by 1
since the following replaces with ${1}1
.
$ script '${1}1'
${1}1${1}1
Problem 2:
$ script '\${ system "echo rm -rf /" }'
rm -rf /
Use of uninitialized value in substitution iterator at a.pl line 12.
rm -rf /
Use of uninitialized value in substitution iterator at a.pl line 12.
Problem 3:
$ script '$1{ system "echo rm -rf /" }'
rm -rf /
Use of uninitialized value within %1 in string at (eval 1) line 1.
rm -rf /
Use of uninitialized value within %1 in string at (eval 2) line 1.
Surely, there are others. Solution:
Use String::Substitution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With