develooper Front page | perl.perl5.porters | Postings from March 2013

Re: [perl #116823] Regexp::Grammars broken since 5.17.1

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
March 10, 2013 00:48
Subject:
Re: [perl #116823] Regexp::Grammars broken since 5.17.1
Message ID:
20130310004816.GT2294@iabyn.com
On Sat, Mar 02, 2013 at 07:26:21PM -0800, Andrew Rodland via RT wrote:
> I distilled it down as far as I could in the attached file. Here's a 
> snippet of "perlbrew exec perl rgtest.pl":

Thanks for the reduced test case.

My preliminary analysis is that

1) the test script (and thus presumably Regexp::Grammars) only worked
because it was inadvertently exploiting a hole in the "use re eval"
mechanism, and that perl 5.17.x is correctly refusing to execute the code;

2) but looking at ways in which Regexp::Grammars should be modifiable to
"play nicely" aren't in fact working, which indicates that there are bugs
in the new perl mechanism too, which I'll need to look into further, and
presumably fix.

The basic issue is this line in the  q{""} overload method:

    return '(?{ $RGP::Success = 1 })' . $$re;

this is basically creating an arbitrary string at run-time, which is
subsequently interpreted as as a pattern: which *should* cause the fatal
error. For example, modifying that line to:

    return '(?{ $RGP::Success = 1 })' . $ARGV[0] . $$re;

and when run as:

     perl5162 -w ~/tmp/rgtest.pl '(?{ system "echo hacked"})'

you get:

    hacked
    ok 1 - It matches
    ok 2 - Code ran
    1..2

which shows that perl is executing code in arbitrary run-time strings
without 'use re eval' in scope.

The basic rule for 5.17.1 onwards is that literal text containing (?{})
that is within a pattern doesn't need 'use re eval'; everything else
should.  This is in many ways a relaxing of the constraints from earlier
perls: this now works without 'use re eval', even though it is a run-time
pattern:

    $x = "foo"; $x =~ /(?{ print "boo\n" })$x/;

while other things that were lax have been stiffened.

However, I would expect something like the following *should* work and be
safe, but it doesn't:

    use re 'eval'; return qr/(?{ $RGP::Success = 1 })$$re/;

And as you pointed out,  a 'use re eval' even in the scope of the main
qr/foo/ doesn't turn off the fatal error. So there's definitely something
there needing more work.

-- 
You never really learn to swear until you learn to drive.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About