Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: Knowing when a code string contains code that will be executed at compile-time/end? (updated)

by haukex (Archbishop)
on Aug 15, 2020 at 08:03 UTC ( [id://11120765]=note: print w/replies, xml ) Need Help??


in reply to Knowing when a code string contains code that will be executed at compile-time/end?

I am given a code string by user, and wants to know if the code contains statements or special blocks that are executed not in regular run time.

Impossible with a static parse (Update: the classic links on "only perl can parse Perl": On Parsing Perl and Perl Cannot Be Parsed: A Formal Proof, and tye's reply to the latter). Consider for example eval(uc('end').'{...}') or something more convoluted, like variations on s s s END { ... } see (Update 3: like s x x qq s \Uens.'D{...}' xexe).

The only way to do this safely is to limit the user to a subset of Perl that is statically parseable. See the new module standard and Sawyer's recent talk on it.

Update 2: As LanX points out, B::Deparse is not perfect, and using standard unfortunately doesn't protect you from those issues either. It would be possible to keep both the original standard-conforming string (checked to ensure it doesn't contain any BEGIN, eval, do, use, and so on) and its evaled coderef, e.g. in an object that could overload stringification and coderef-dereferencing, but that might be overkill depending on what you're trying to do.

  • Comment on Re: Knowing when a code string contains code that will be executed at compile-time/end? (updated)
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Knowing when a code string contains code that will be executed at compile-time/end?
by LanX (Saint) on Aug 15, 2020 at 09:23 UTC
      They should show up when applying B::Deparse

      Nope, as the OP shows. Plus deparsing requires an eval of the string first.

      use warnings; use strict; use B::Deparse; my $code = q{ print "code\n"; s s s END { print "end\n" } see }; my $coderef = eval qq{ sub { $code } }; my $deparse = B::Deparse->new(); $deparse->ambient_pragmas(strict => 'all', warnings=>'all'); print $deparse->coderef2text($coderef), "\n"; __END__ { print "code\n"; s/ /();/ee; } end

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (None)
    As of 2024-04-25 00:02 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found