Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Small examples of string eval

by BrowserUk (Pope)
on May 13, 2006 at 10:20 UTC ( #549210=note: print w/ replies, xml ) Need Help??


in reply to Small examples of string eval

I have several scripts that take numeric arguments from the command line where is is extremely useful to be able to enter expressions instead of simple values.

#! perl -slw use strict; our $LIMIT = eval $LIMIT || 'somedefault';

This way I can specify

script -LIMIT=2**33 or script -LIMIT=8*1024**3

Which beats the crap out of trying to remember

script -LIMIT=8589934592

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.


Comment on Re: Small examples of string eval
Select or Download Code
Re^2: Small examples of string eval
by brian_d_foy (Abbot) on May 14, 2006 at 17:16 UTC

    You don't need eval for that, even if it makes it easier than parsing the argument and figuring out the value. The downside is that anyone can run arbitrary code using your script. With a tiny bit of programming you can do the math yourself and save yourself the security problem. :)

    --
    brian d foy <brian@stonehenge.com>
    Subscribe to The Perl Review
      anyone can run arbitrary code using your script ...

      Apart from the fact that only I run the scripts in question, those same bad people you are parnoid about could also type perl -e"the same arbitrary code"

      With a tiny bit of programming ...

      Show me the code.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        These discussion typically start with "only I run the script", and that's just a lack of imagination. You know better than that. And, it's not just a script you're running. You're telling the world it's a good idea to follow your example. You know that's not the right thing to do, and you know it's hazardous.

        The expression code is easily handled by Math::Expression (on CPAN), like everything else you want to do. This is what I use when I need this, although I had to modify the source to add ** as an operator (but that's really easy and I'm sure you'll figure it out as easily as you could have found this module, but I'll include the patch for everyone else).

        #!/usr/bin/perl use Math::Expression; my $expr = Math::Expression->new; my $tree = $expr->Parse( "8*1024**3" ); my $answer = $expr->EvalTree( $tree, 0 ); print "My answer is $answer\n";

        And, as you know, security is subverted by a combination of factors. You know that you've taken a shortcut and you know what the problem is. If someone can coerce your code to running as your userid (perhaps through changing the file mode, or even just changing a shell script that uses this script), they have their in. Again, as you know, security happens in layers and you do what you can to prevent unintended uses. You know that your eval shortcut can do a lot more than you want, and you also don't care to make the easy (and re-usable) fix. That's why some people have to be paranoid. :)

        58,59c58,59 < my $HighestOperPrec = 15; < my $PrecTerminal = 16; # Precedence of terminal (or l +ist) - ie operand --- > my $HighestOperPrec = 14; > my $PrecTerminal = 15; # Precedence of terminal (or l +ist) - ie operand 61,65c61,64 < '(' => [17, 17], < 'var' => [16, 16], < 'const' => [16, 16], < 'func' => [16, 16], < '**'=> [15, 15], --- > '(' => [16, 16], > 'var' => [15, 15], > 'const' => [15, 15], > 'func' => [15, 15], 170c169 < --- > 180c179 < elsif($expr =~ s@^(:=|>=|<=|==|<>|!=|&&|\|\||lt|gt|le| +ge|eq|ne|\ *{2}|[-./*%+,<>\?:\(\);])@@) { --- > elsif($expr =~ s@^(:=|>=|<=|==|<>|!=|&&|\|\||lt|gt|le| +ge|eq|ne|[ -./*%+,<>\?:\(\);])@@) { 480d478 < return $left ** $right if($oper eq '**'); + +

        Maybe you don't want to use a module, though, and that's fine. That's a better reason than "that will never happen". There are all sorts of other things you can do to harden your code, but you have to want to do that. At the very least, turn on taint checking and scrub the input.

        --
        brian d foy <brian@stonehenge.com>
        Subscribe to The Perl Review

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://549210]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (9)
As of 2014-07-29 06:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (211 votes), past polls