Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

evaluating syntax of code blocks (code)

by deprecated (Priest)
on Jul 02, 2001 at 05:12 UTC ( [id://93089]=perlquestion: print w/replies, xml ) Need Help??

deprecated has asked for the wisdom of the Perl Monks concerning the following question:

Lets say I have this code:
sub myFunc { $foo = shift; $foo++ $foo; }
See the small syntax goof? I'm missing a semi. I am making an object which can have code blocks added to it for later execution. But I want to check those code blocks to make sure they are good.

Something like this:

$obj -> addFunc( \&myFunc );
So, um, how do I make sure that the programmers using my API are not giving me bogus code?

thanks,
brother dep

--
Laziness, Impatience, Hubris, and Generosity.

Replies are listed 'Best First'.
Re: evaluating syntax of code blocks (code)
by tachyon (Chancellor) on Jul 02, 2001 at 09:22 UTC

    You could do something like this and eval the code you are being given but use a bareblock and a last to ensure that it COMPILES but does not actually ever RUN. The last causes an immediate exit from the block. Comment out the $code = "{last; $code}" to see how this works.

    Even using this methodology a malicious coder could force code execution if you allow BEGIN blocks. Comment out the s/BEGIN// to see what I mean. BEGIN {`format C:`} might be a bit of a bummer so we kill these off. By deleting the 'BEGIN' they become ordinary blocks that will never execute owing to the {last; ... } structure.

    There may be other security holes in this solution, no doubt they will be duly noted. I used this method in a script (not a CGI!) a while ago because I was totally unable to capture the output of perl -c - it goes to STDOUT on Win32 despite all efforts otherwise. Perl -c also allows BEGIN blocks to !$#% you over as they get EXECUTED even though the rest of the code does not. Abigail has demonstrated a virus based on this behaviour BTW.

    Update

    jplindstrom reminded me about END blocks and I refresh my memory on CHECK blocks - both these will execute in this structure so I have updated the code to just remove all the blocks constructs.

    cheers

    tachyon

    $code = <<'CODE'; print "Hello World!\n"; BEGIN {print '# hacked #';} CODE $code =~ s/BEGIN|CHECK|INIT|END//g; # kill blocks here $code = "{last; $code}"; # stop test code running eval $code; # now have a look see at $@ to see if it contains an error # due to the test code being invalid. print $@ ? "Invalid\n" : "Syntax OK\n";
      Cool, but don't forget

      $code = <<'CODE'; END {print '# post-hacked #';} print "Hello World!\n"; CODE
      the END block.

      /J

        Thanks, forgot about them. CHECK blocks will also do the trick so best to remove all of the BEGIN|CHECK|INIT|END blocks.

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n\w+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: evaluating syntax of code blocks (code)
by kschwab (Vicar) on Jul 02, 2001 at 05:32 UTC
    Something like that was discussed before over here. As I remember it, there wasn't a good, safe solution. If, however, your API is being called in the programmer's environment, and not yours, that node may be useful.
Re: evaluating syntax of code blocks (code)
by MeowChow (Vicar) on Jul 02, 2001 at 06:52 UTC
    If your API is such that you are given a reference to a block of code (which is what your sample code indicates), then by definition, Perl has already parsed and verified the code's syntax as being correct, and there is no need for you to do so.
       MeowChow                                   
                   s aamecha.s a..a\u$&owag.print
      Perl has already parsed and verified the code's syntax as being correct,
      Acting as deprecated's spokesperson, what he means is that the syntax projected into undesired semantics... had the semicolon been after the autoincrement, the projection would have been the intended one.

      One simple thing you can do is see if a line does not end in semicolon... assuming the program statements are simple, then each line shouldend with semicolon.

        I'm not sure I understand what you mean by "projected into undesired semantics". The myFunc that deprecated provided as an example will not compile, hence, it has no semantics to speak of.
           MeowChow                                   
                       s aamecha.s a..a\u$&owag.print
Re: evaluating syntax of code blocks (code)
by TheoPetersen (Priest) on Jul 02, 2001 at 05:39 UTC
    I can't think of any easy way of checking the syntax without leaving the interpreter. But if those code blocks are only added occasionally, you could spool the new code out to a file and use perl -c to verify the syntax.
Re: evaluating syntax of code blocks (code)
by mikeB (Friar) on Jul 02, 2001 at 18:52 UTC
    If you're concerned about malicious code, you might consider use Safe; to run the code in a sandbox with the more 'dangerous' ops disabled.
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://93089]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (8)
As of 2024-04-24 09:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found