当用户输入右侧时,通过s///操作符安全地使用ee修饰符 [英] Using the ee modifier safely with the s/// operator when the right side is input from user

查看:47
本文介绍了当用户输入右侧时,通过s///操作符安全地使用ee修饰符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个Perl脚本,用户可以在其中输入正则表达式和替换字符串.该脚本将搜索一组文件并根据与用户输入一起应用的perl s///运算符应用更改.

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.

为了使事情复杂一些,允许替换字符串包含反向引用,以引用正则表达式中的捕获组.例如,如果正则表达式为b(.*?)a且替换字符串为a$1b,则$1不应按字面意义对待,而应将其视为捕获第一组的后向引用.

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.

在这种设置下,我想知道当s///运算符的右侧输入时,是否可以通过s///运算符安全地使用ee修饰符(以评估用户输入中的后向引用).用户?例如:

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;

对我来说,这乍看起来似乎奏效,还是我错过了什么? 例如,如果脚本名为test.pl并且用户以以下方式运行它:

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 ):

做{"a $ b"}做{"a $ b"}

do{ "a$b" }do{ "a$b" }

问题是:这真的是一种安全/正确的方法吗?

So the question is: Is this really a safe/correct approach?

推荐答案

问题1:

由于以下内容替换为${1}1,因此无法替换为$11.

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


问题2:


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.


问题3:


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:

使用 String :: Substitution .

这篇关于当用户输入右侧时,通过s///操作符安全地使用ee修饰符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆