Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

when eval corrupts the invoker

by epoptai (Curate)
on Jun 24, 2002 at 22:23 UTC ( #176968=perlquestion: print w/replies, xml ) Need Help??

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

I recently added a script called MODULATOR (updated) to the catacombs and have a question about the unexpected results of one of its functions. When viewing POD this script optionally puts the example code from the "synopsis" section into a form so it can be tested using eval. This works well most of the time but the Acme brand of modules is causing problems. If the example code from say Acme::Bleach:
use Acme::Bleach; print "Hello world";
is evaluated, the modulator script is wiped out and replaced with the output of Bleach, namely a file full of invisible characters with "use Acme::Bleach" at the top, and it ceases to function at all.

  1. Is there a way to prevent this unfortunate outcome besides preventing certain naughty modules from the eval?
  2. Are there any other modules besides the Acme brand that involve this kind of danger to the invoking script?

Thank you for your consideration of this matter.

Check out my Perlmonks Related Scripts like framechat, reputer, and xNN.

Replies are listed 'Best First'.
•Re: when eval corrupts the invoker
by merlyn (Sage) on Jun 24, 2002 at 23:40 UTC
    Well, anybody can put unlink $0 in their synopsis section. Or even system "rm","-rf",$ENV{HOME}. You really should be using Safe instead of eval.

    -- Randal L. Schwartz, Perl hacker

      Since this is a utility script for use by people who know Perl I'm not too worried about deliberately dangerous input, just the off chance that someone will test an Acme module and accidentally toast the script.

      To summarize, after kicking it around the CB with fever and jarich it was revealed that Safe doesn't seem to allow use or require in its compartments, so it won't help in this case, since use is required (pun not intended but what the heck). Other ideas were to lock $0 somehow (Zaxo) or back it up in case of emergency, but I finally settled for not putting the example code from modules known to modify $0 into a form.

      Update: changed to perigeeV's brilliant strategy of redefining $0 in a begin block.

      ps - Mr. Muskrat, I know exactly what bleach does and that is what I'm trying to prevent ;^)

      Check out my Perlmonks Related Scripts like framechat, reputer, and xNN.

Re: when eval corrupts the invoker
by toma (Vicar) on Jun 25, 2002 at 07:27 UTC
    It would be useful to maintain a list of CPAN modules that have unusual behavior such as Acme::Bleach. Perhaps MODULATOR could detect these modules and automatically update the list.

    If these source-modifying modules all had antidotes with a common naming convention, then MODULATOR could check for self modification and run the antidote if necessary.

    I wrote a program to reverse the effects of Bleach. I called it

    If more people give in to the temptation of writing perl code that has unusual side effects, validation will grow in importance. There is potential for harm in many more ways than modifying source code, as merlyn points out. A validation program could use checksums, take advantage of MANIFEST information, etc. It could also be useful for checking for non-perl applications.

    It should work perfectly the first time! - toma

Re: when eval corrupts the invoker
by Mr. Muskrat (Canon) on Jun 25, 2002 at 02:32 UTC
    Did you RTFM for Acme::Bleach?
    Because it looks like it is behaving normally under those conditions.

    Who says that programmers can't work in the Marketing Department?
    Or is that who says that Marketing people can't program?
Re: when eval corrupts the invoker
by perigeeV (Hermit) on Jun 25, 2002 at 16:27 UTC

    $0 is Lvaluable so you could anticipate any changes to it. Simplistically you could just:

    BEGIN{$0 = "foo"}

    Or if you want to watch it's state just tie the thing:

    package Progname; use Carp; sub TIESCALAR { my $class = shift; my $newname = shift; return bless \$newname, $class; } sub FETCH { my $self = shift; carp "The program name is being accessed.\n"; return $$self; } sub STORE { my $self = shift; my $attempted = shift; carp "An attempt is being made to change the program name to \"$at +tempted\".\n"; } 1;

    And then:

    use Progname; tie $0, 'Progname', "NewProgramName";

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://176968]
Approved by virtualsue
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2021-05-12 05:05 GMT
Find Nodes?
    Voting Booth?
    Perl 7 will be out ...

    Results (124 votes). Check out past polls.