Evaluating user-defined conditions

Abigail abigail at abigail.be
Tue Jun 10 12:43:52 BST 2014


On Tue, Jun 10, 2014 at 12:06:21PM +0100, Andrew Beverley wrote:
> On Tue, 2014-06-10 at 12:23 +0200, Abigail wrote:
> > Note that all you need is a *validating* parser. You don't have to bother
> > with building a parse tree, and evaluating the results -- *that* can be
> > left to Perl.
> 
> Ah, okay, thanks.
> 
> > Here's a pattern that accepts expressions of the form you initially 
> > posted (and I've replaced [var] with "var"):
> > 
> > 
> > #!/usr/bin/perl
> > 
> > use 5.010;
> > 
> > use strict;
> > use warnings;
> > no  warnings 'syntax';
> > 
> > use Test::Regexp;
> > use Test::More;
> > 
> > my $pat = qr {
> >     (?(DEFINE)
> >        (?<expression>     (?&term)
> >                           (?: \ * (?: [-<>+*] | && | eq ) \ * (?&expression))?)
> >        (?<term>        \( (?&expression) \) |
> >                            " [a-z]+ "       |
> >                              [0-9]+))
> >     ^(?&expression)$
> > }x;
> > 
> > my $test = Test::Regexp:: -> new -> init (
> >                  keep_pattern    => $pat,
> >                  no_keep_message => 1,
> >                  name            => "Expression"
> > );
> > 
> > #
> > # Using (?<name>PAT) leaves traces in %- behind, even if they don't
> > # actually capture...
> > #
> > my $captures = [[expression => undef],
> >                 [term       => undef]];
> > 
> > 
> > $test -> match ('"age" > 10 && "price" < ("age" + 5) * 10',
> >                  captures => $captures);
> > 
> > $test -> no_match ('"@{qx (rm -rf)}" && 1');
> > 
> > 
> > done_testing;
> > 
> > __END__
> 
> Brilliant, thanks for that, much appreciated. However, isn't that
> similar to what I was trying to do, in that you're relying on the regex
> to match (or otherwise) accordingly?

Two key differences:
    - Your approach basically is "allow anything, except for the things
      matched", whily my approach is "only allow if matched".
    - You looked at the expression in a very localized way, while my
      patterns looks at the complete expression.

>                                      And you'd still need to eval it
> afterwards?
> 
> I'm going to need to allow strings to be matched. E.g:
> 
> [age] > 10 && [name] eq "jon"

Allow any string? Including strings that may potentially excute code?
In that case, eval will be wrong. Or is the string just a list of 
alphanumerics? In which case, just add another clause to the definition
of term.

> 
> which sounds dangerous for the very good reasons you outlined previously
> (thanks for that - glad that I asked!)



Abigail


More information about the london.pm mailing list