in reply to Can you check the syntax of a eval() before executing it?

The generally accepted way to do this is to prefix the eval code with "return;", so you'd do:
eval "return;" . $code;
However it won't prevent the execution of BEGIN blocks, and when you want to execute it, you have to compile it again.

Replies are listed 'Best First'.
Re: Re: Can you check the syntax of a eval() before executing it?
by Dog and Pony (Priest) on May 06, 2002 at 23:41 UTC
    Another, possibly sillier way would be to eval it into an anonymous subroutine:
    my $coderef = eval "sub{$code}" or die "Error in code: $@"; $coderef->(); # execute the code
    That way one wouldn't have to recompile the code, if you really need that kind of optimization. It is also quite possible that there is code that can't be evaled into a sub like this. But maybe it'll suffice. :)
    You have moved into a dark place.
    It is pitch black. You are likely to be eaten by a grue.

      ... and it still executes those pesky BEGIN blocks.

      Some days you just have to love Perl's DWIDM features.

        That is true. I can see no good way to avoid that, either. Something like:
        my $coderef = eval "BEGIN{goto skip;}sub { $code } BEGIN{skip: print ' +Skipped!'}";
        will not work. Not that I am sure it would be good if it did either... return and exit both also yield unsatisfying results, not surprisingly.

        However, if you are afraid that someone might execute harmful code, then that is a whole nother issue, and you will not be protected just by verifying the syntax (which was what I addressed). However, if you use Safe, and do like this:

        use Safe; my $compartment = new Safe; my $coderef = $compartment->reval("sub{$code}") or die "$@"; $coderef->(); # execute the code
        The Safe compartment will stop whatever you decide is harmful code even in BEGIN blocks.

        If the issue rather is that it is annoying that code will become executed, well then some kind of filter might be in place I guess. For instance, for nearly all applications I could think of (short of a perl editor of course) disallowing the word "BEGIN" in the input (possibly in special cases, like followed by braces) would not be a big problem, would it?

        It is definetely something to be aware of though. Good call. :)


        You have moved into a dark place.
        It is pitch black. You are likely to be eaten by a grue.
Re: Re: Can you check the syntax of a eval() before executing it?
by graff (Chancellor) on May 07, 2002 at 13:49 UTC
    Well, if we want to be really careful about checking what $code is going to do, why not do some more analysis of its content:
    my $codeBegin = ""; if ( $code =~ /BEGIN\s*\{/ ) { # tricky part here: try to locate the matching close brace # (this would require parsing character-by-character, to # handle various quote operators and escapes -- a worthwhile # project for a module developer, not something I can do here). # check that part separately, assign it to $codeBegin and # delete it from $code; } # now check whatever's left in $code, and if everything's # okay, then: eval "$codeBegin $code";
    But would we also have to check separately for an END{} block?