The former behavior is documented in perlop, under the "Binding Operators" section, where it states:
If the right argument is an expression rather than a search pattern, substitution, or transliteration, it is interpreted as a search pattern at run time.
This is a slightly dangerous behavior, though no more so than the act of passing a user-supplied pattern as $data =~ m/$user_pattern/. A user could supply a masterfully crafted (or simply grossly naive) pattern that results in massive amounts of memory consumption and near infinite looping inside the regex engine. And it's next to impossible to pre-process the user-supplied pattern in a way that will prevent this potential risk while at the same time retaining the legitimate functionality of the regex language.
To get the ability for a user-supplied operator (such as s///) to be executed, you've got a couple of choices: One is to elevate your security risk a few levels higher by using string eval to evaluate the user-supplied code (this is usually a bad idea). Another is to create logic in your program that allows a user to specify whether he wants substitution or simple matching, and then supply the operators yourself. For example:
use strict; use warnings; my $data = "Just another Perl hacker,"; my $action = 'subst'; my $pattern = 'hacker'; my $substitution = 'enthusiast'; my %actions = ( match => sub { my $rv = $_[0] = ~m/$_[1]/; return( $rv, [@-], [@+] ) +}, subst => sub { my $rv = $_[0] =~ s/$_[1]/$_[2]/; return( $rv, [@_], [@+] ) +}, ); exists $actions{$action} or die "Invalid action: $action"; my @results = $actions{$action}->($data, $pattern, $substitution); print $data, "\n";
With a little thought, and a better understanding of the exact problem you're trying to solve, you could probably come up with even simpler dispatch table callbacks...or could add additional return values as needed. But the point is that here we're avoiding evaluating user-supplied code directly, although we still have the problem of the user possibly supplying a nasty regex.
Dave
In reply to Re: using just variables in a regular exression
by davido
in thread using just variables in a regular exression
by sdetweil
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |