in reply to Store regex modifiers in variables?
You can also do it using an eval which is perhaps more obvious than no_slogan's method but not as elegant.
$_ = 'foo('; $regex = 'FOO('; $modifiers = 'i'; # a bit of error checking never goes astray die "Illegal modifier!" unless $modifiers =~ m/^[ismxo]\z/; # escape everything except the essential regex char and \w \s # this is a security measure as discussed below $regex =~ s/([^\w\s\\|()[\]{}^\$*+?.])/\\$1/g; # generate the regex with error checking $regex = eval "qr/$regex/$modifiers"; die "Eval failed $@\n" if $@; # test it print "match" if /$regex/;
There is a significant security issue eval-ing user supplied data, or in fact using raw user data in many places in a script. The problem is scary. If $regex contains a string like this '/; `some bad command`; $hacked =1' then when this interpolates we will eval
$regex = eval "qr//; `some bad command`; $hacked =1/$modifiers"
This may execute some bad command on your system with the same permissions as the script. Both the solutions presented suffer from this problem. To solve it (at least partially) you need to escape all the non regex metachars.
$regex =~ s/([^\w\s\\|()[\]{}^\$*+?.])/\\$1/g;
This will leave \w \s and the regex chars unescaped but throw in escapes for everything else including semicolons and backtics. It can probably still be hacked - did someone say merlyn - but the escapes should throw a spanner in the works for the casual hacker.
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
|
|---|