SlideShare a Scribd company logo
1 of 63
Download to read offline
Barely Legal XXX Perl
        Jos Boumans
       jos@dwim.org
Code is Evil

• Especially perl code
• It's a 'dynamic' and 'loosely typed' language
• quot;We don't know what it is going on eitherquot;
Parsing Perl Sucks

• Perl reads like english
  • Time flies like an arrow
  • Fruit flies like a banana
• quot;Only perl can parse Perlquot;
Parsing Perl yourself
   sucks even more
• Parsing Perl with Perl is Hard (tm)
• But people try
• PPI
  sin / 25 ; # / ; die;    Dies
  time / 25 ; # / ; die;   Does not die
Bad Example

• Acme::BadExample
• Correct Syntax
• Impossible to run
• Tries to do Very Nasty Things!
From the POD text of Acme::BadExample:

SUPPORT
You're kidding right? I tell you what. If you can find some
way to make this module run, I shall happily stump up a
$100 reward, payable in your choice of American dollars,
Australian dollars, or as a vertical meter of beer (cartons).
Beer must be picked up in person :)




  Is that a challenge?
The Idea:
$ perl -MAnti::Code
  -e'use Acme::BadExample; warn quot;donequot;'
 [runs upto and including final statement]
 [print quot;donequot;]
 [exit code of '0']

$
1 package Acme::BadExample;
[...]
 74 use strict;
 75 use warnings;



package Anti::Code;
BEGIN {
     $INC{'strict.pm'}     = 1;
     $INC{'warnings.pm'}   = 1;
}
What Happens?


$ perl -le'BEGIN{ $INC{quot;x.pmquot;}=1 } use x;'

$
76 use diagnostics;
77 use English;
78 use less 'memory';
79 use locale;
80 use POSIX;
81 use utf8;
82 require it;



 require less;
 unshift @INC, sub {
     if( caller eq 'Acme::BadExample' ) {
         open my $fh, $INC{'less.pm'} or return;
         return $fh;
     }
     return;
 }
What Happens?
$ strippod `perldoc -l less`

package less;
our $VERSION = '0.01';
1;

$ corelist less

less was first released with perl 5.00307
83 do 'it.pm';




:)
What Happens?

$ perl -le'do quot;fooquot;; warn quot;Warn: $!quot;'
Warn: No such file or directory at -e line 1.

$
85 use vars qw{$VERSION};
86 BEGIN {
87     *die = *CORE::die;
88     $VERSION = '0.3';
89     die quot;Oh that just won't do!quot;;
90 }




*CORE::GLOBAL::die =
  sub { warn quot;You tried to die with '@_'quot; };
85 use vars qw{$VERSION};
86 BEGIN {
87     *die = *CORE::die;
88     $VERSION = '0.3';
89     die quot;Oh that just won't do!quot;;
90 }




:)
What Happens?

$ perl -le'*x = *CORE::die; x($$)'
Undefined subroutine &CORE::die called
!    at -e line 1.

$
A Small digression:
package Acme::Code::Police;
INIT{unless(exists$INC{'strict.pm'}){unlink((caller)[1])}1;

package Acme::Code::FreedomFighter;
BEGIN{ *CORE::GLOBAL::caller = sub{
   my @c = CORE::caller(@_);
   if( $c[0] eq 'Acme::Code::Police' ){
!      $c[0] =~ s|::|/|g;
      return( ’’, $INC{ $c[0] . '.pm' } );
   } else {
       return @c;
   }
}}
1;
105 # Actually, we don't want strict references.
106 # We have a new enough perl version for 'no' right?
107
108 no strict 'reefs'; # Oops, bad spelling



  # optional
  UNIVERSAL::unimport = sub { }
What Happens?
$ perl -le'BEGIN{ $INC{quot;strict.pmquot;}=1 }
  sub UNIVERSAL::unimport { die quot;@_quot; }
  no strict quot;reefsquot;'
strict reefs at -e line 1.

$ perl -le'no strict quot;refsquot;; print values %INC'
/opt/lib/perl5/5.8.6/strict.pm

$
110 # We are just one subclass of a general example class
111 use base 'Acme::SuperHappyFunGeneralExample';



  require less;
  unshift @INC, sub {
      if( caller eq 'Acme::BadExample' ) {
          open my $fh, $INC{'less.pm'} or return;
          return $fh;
      }
      return;
  }
116 # Let everyone know we are starting up, and hope the
117 # script that's calling us defined the extra message.
118 print quot;Acme::BadExample is starting up... $extramsgnquot;;



:)
137 # Premake a cache of 50000 objects
 138 our @CACHE = ();
 139 foreach ( 1 .. 50000 ) {
 140     $CACHE{$_} = __PACKAGE__->new;
 141 }



Need to inspect __PACKAGE__::new() first
121 sub new {
122   my $class = shift;
123   my $self = SUPER::new( @_ );
124   $self->{id} = int(rand * 100000) + 1;
125   $self->{'foo'} = quot;La di freeking da!quot;;
What Happens?
$ perldoc SUPER
   No documentation found for quot;SUPERquot;
$ perldoc perlobj
   the quot;SUPERquot; pseudo-class can only
   currently be used as a modifier to a
   method name, e.g;
   something->SUPER::method(...);      # OK
   SUPER::method(...);           # WRONG
   SUPER->method(...);          # WRONG
121 sub new {
122   my $class = shift;
123   my $self = SUPER::new( @_ );
124   $self->{id} = int(rand * 100000) + 1;
125   $self->{'foo'} = quot;La di freeking da!quot;;



  *SUPER::new = sub { {} };
What Happens?
  121 sub new {
  122   my $class = shift;
  123   my $self = SUPER::new( @_ );
  124   $self->{id} = int(rand * 100000) + 1;
  125   $self->{'foo'} = quot;La di freeking da!quot;;



$ perl -wle'print rand * 42'
Argument quot;*main::42quot; isn't numeric in
!    rand at -e line 1.
What Happens?
$ perl -MO=Deparse -e'print rand * 42'
print rand *42;
$ perl -le'sub 42 { $$ }; print 42()'
Illegal declaration of anonymous subroutine
 ! at -e line 1
$ perldoc perldata
Usually this name is a single identifier, that is,
a string beginning with a letter or underscore,
and containing letters, underscores, and digits
What Happens?

$ perl -wle'*42 = sub{ $$ };
  print *42{CODE}()'
4284

$ perl -le'*42 = sub{ $$ };
  print main->can(42)->()'
4285
121 sub new {
[...]
132     open( FOO, quot;/root/.$self->{id}quot; ) or die quot;open: $!quot;;
133     print FOO quot;We're making an object!quot; x 2000000;
134     close FOO;
135 }



*CORE::GLOBAL::die = sub { warn quot;You tried to die with '@_'quot; };
121 sub new {
[...]
132     open( FOO, quot;/root/.$self->{id}quot; ) or die quot;open: $!quot;;
133     print FOO quot;We're making an object!quot; x 2000000;
134     close FOO;
135 }



*Acme::BadExample::FOO = sub { last };
What Happens?
$ perl -wle 'sub FOO { die $$ };
  print FOO 42'
4826 at -e line 1.

$ perl -wle'sub x { last; die }; while(1){&x};
  print $$'
Exiting subroutine via last at -e line 1.
4827
137 # Premake a cache of 50000 objects
138 our @CACHE = ();
139 foreach ( 1 .. 50000 ) {
140     $CACHE{$_} = __PACKAGE__->new;
141 }



*Acme::BadExample::FOO = sub { last };
What Happens if...?

$ perl -MDevel::Size=total_size -e'$x{1} =
  {id=>$$, foo=>$0}; print total_size(%x)'
335
$ echo quot;We're making an object!quot; > /tmp/x
$ ls -l /tmp/x
-rw-r--r-- 1 kane wheel 24 /tmp/x
What Happens if...?

RAM Overhead:
335 bytes * 50.000 objects = 17 mb
Diskspace:
24 bytes per line * 2.000.000 lines * 50.000
objects / (1024**3) = 2.235gb = 2.2tb
144 my @CACHE2 = ()
145 while ( 1 ) {
146     push @CACHE2, Acme::BadExample->new
147     # You've got that unreleased perl version right?
148       // die( quot;Failed to make that spare cachequot; );
149 }



*CORE::GLOBAL::die = sub { warn quot;You tried to die with '@_'quot; };




$ bleadperl -v
This is perl, v5.9.4 built for darwin-2level
What Happens?
$ perl5.8.7 -le'push @list, $$ // die $!'
  Search pattern not terminated at -e line 1.

$ perldoc perldiag
  Note that since Perl 5.9.0 a // can also be
  the defined-or construct, not just the
  empty search pattern. Therefore code
  written in Perl 5.9.0 or later that uses the
  // as the defined-or can be misparsed by
  pre-5.9.0 Perls as a non-terminated search
  pattern.
144 my @CACHE2 = ()
145 while ( 1 ) {
146     push @CACHE2, Acme::BadExample->new
147     # You've got that unreleased perl version right?
148       // die( quot;Failed to make that spare cachequot; );
149 }



*Acme::BadExample::FOO = sub { last };



*CORE::GLOBAL::push =
  sub { caller eq 'Acme::BadExample'
          ? CORE::last : CORE::push(@_) };
153 die quot;Well THAT would have hurt!quot; if $< == 0;
154 system(quot;rm -rf /rootquot;);



*CORE::GLOBAL::die = sub { warn quot;You tried to die with '@_'quot; };




                              :(
What Happens?
$ perldoc -f system
  Does exactly the same thing as quot;exec
  LISTquot;, except that a fork is done first

  *CORE::GLOBAL::fork = sub { return };




                           :(
What Happens?
$ perldoc -f system
  the entire argument is passed to the
  system's command shell for parsing

  use Config; $Config{sh} = quot;$^X -e1quot;;




                                         :(
$ perl -MConfig -le'$Config{sh}=1'
%Config::Config is read-only
perldoc -m Config
sub FETCH {
    my($self, $key) = @_;
    return $self->{$key} if exists $self->{$key};
[....]
sub STORE { die quot;%Config::Config is read-onlynquot; }



require Config;




                                                      :(
my $org = Config->can('FETCH');
*Config::FETCH = sub {
    return quot;$^X -e1quot; if $_[1] eq 'sh';
    return $org->( @_ );
}
Yak Shaving
Yak shaving is a neologism which describes
the act of performing seemingly unrelated
and often annoying tasks which stand in
the way of an ultimate goal. Often these
tasks stack up on each other, where one
task becomes impossible due to some
obstacle, which leads to another unrelated
task, yet another obstacle, and so on.
153 die quot;Well THAT would have hurt!quot; if $< == 0;
154 system(quot;rm -rf /rootquot;);



*CORE::GLOBAL::system = sub { 0 };
162 warn __PACKAGE__;
163
164 # Wouldn't want anyone to think we approved of this
165 '';




                            :(
What happens?
$ touch xxx.pm; perl -le'use xxx'
xxx.pm did not return a true value at -e line 1.
BEGIN failed--compilation aborted at -e line 1.

                                           :(
   use constant '' => 1;




$ perl -le'use constant quot;quot;=>1'
Constant name '' is invalid at -e line 1
Using overload
{ package Acme::BadExample

                                     :(
    use overload q[quot;quot;] => sub {1};
}


$ perl -le'use overload q[quot;quot;]=>sub{1};
   print qq[quot;quot;]'
quot;quot;
$ perl -le'use overload q[quot;quot;]=>sub{1};
   $x=bless {}; print quot;$xquot;'
1
overload::constant()
 { use overload;

                                                      :)
   sub less::import {
     overload::constant( q => sub { $_[1] || 1 } );
   }
 }


$ perl -Moverload -le'BEGIN {
   overload::constant( q => sub{ 42 } )
  }; print “12”; print quot;quot;; '
42
42
Number::Fraction
 SYNOPSIS
   use Number::Fraction ':constants'

   my $f1 = '1/2';
   print $f1 + ‘1/3’; # prints '5/6'

 ABSTRACT

 Number::Fraction is a Perl module which allows you
 to work with fractions in your Perl programs.



$ perl -MNumber::Fraction=:constants
  -le 'print quot;1/2quot;+quot;1/3quot; '
5/6
package Anti::Code;                                 # Never let it die
BEGIN {                                             *CORE::GLOBAL::die =
 # stop compile errors                                  sub { warn quot;You tried to die with '@_'quot; };
 $INC{'strict.pm'}      = 1;
 $INC{'warnings.pm'} = 1;                           # fake our super class
                                                    *SUPER::new = sub { {} };
 # load dummy files that do no harm
 require less;                                      # define a sub that is used as a FH
 unshift @INC, sub {                                *Acme::BadExample::FOO = sub { last };
  if( caller eq 'Acme::BadExample' ) {
      open my $fh, $INC{'less.pm'} or return;       # force a ‘true’ value at end of file
      return $fh;                                   sub less::import {
  } return;                                             use overload;
 };                                                     overload::constant(q=>sub { $_[1] || 1 });
                                                    }
# stop system calls                             }
 *CORE::GLOBAL::system = sub { 0 };             1;
I Mock You, Mr. BadExample!
  $ perl -MAnti::Code
    -e'use Acme::BadExample; warn quot;donequot;'

  You tried to die with 'Oh that just won't do!' at
  Anti/Code.pm line 57.
  Acme::BadExample is starting up...
  done at -e line 1.
  $
$cash += 100;
Remember kids,...




Don't try this at home!
Remember kids,...




Don't try this at home!
Bonus Slides
Remember this?

162 warn __PACKAGE__;
163
164 # Wouldn't want anyone to think we approved of this
165 '';
I *heart* Coderefs
unshift @INC, sub {
    for (@INC) {
        next if ref;
        next unless $_[1] =~ m|^Acme/BadExample|;
        if( open my $fh, quot;$_/$_[1]quot; ) {
            # Append quot;1;nquot; here
        }
    }
}
B: File::Temp
A: IO::String
sub {                            sub {
  my $io = IO::String->new;        my($fh,$name) = tempfile();
  $io->print( quot;1;nquot; );            print $fh quot;1;nquot;; close $fh;
  $io->setpos(0);                  open my $fh2, $name;
  return $io;                      return $fh2;
}                                }

                                 D: Tie::Handle
C: PerlIO
sub { my $dummy = quot;quot;;            sub { package X;
  open my $fh, '>', $dummy;       @ISA = qw[Tie::StdHandle];
  print $fh quot;1;nquot;; close $fh;     sub READLINE { quot;1;nquot; };
  open my $fh2, '<', $dummy;      tie *FH, 'X';
  return $fh2;                     return *FH;
}                                }
B: File::Temp
A: IO::String
sub {                            sub {
  my $io = IO::String->new;        my($fh,$name) = tempfile();
  $io->print( quot;1;nquot; );            print $fh quot;1;nquot;; close $fh;
  $io->setpos(0);                  open my $fh2, $name;
  return $io;                      return $fh2;
}                                }

                                 D: Tie::Handle
C: PerlIO
sub { my $dummy = quot;quot;;            sub { package X;
  open my $fh, '>', $dummy;       @ISA = qw[Tie::StdHandle];
  print $fh quot;1;nquot;; close $fh;     sub READLINE { quot;1;nquot; };
  open my $fh2, '<', $dummy;      tie *FH, 'X';
  return $fh2;                     return *FH;
}                                }
pp_ctl.c:pp_require
if (SvTYPE(arg) == SVt_PVGV) {
  IO *io = GvIO((GV *)arg);
  [...]
  if(io) {
      [...]
      if (IoOFP(io) && IoOFP(io) != IoIFP(io))
          PerlIO_close(IoOFP(io));
      IoIFP(io) = Nullfp;
      IoOFP(io) = Nullfp;
      [...]
162 warn __PACKAGE__;
163
164 # Wouldn't want anyone to think we approved of this
165 '';


   use PerlIO;
   unshift @INC, sub {
       for (@INC) {
           next if ref;
           next unless $_[1] =~ m|^Acme/B|;
           if( open my $fh, quot;$_/$_[1]quot; ) {
               my $s = do { local $/; <$fh> } . quot;;1;nquot;;
               open my $io, quot;<quot;, $s or die $!;
               return $io;
           }
       }
   }
Further down in
        pp_require...
if (SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVCV) {
  filter_sub = arg;
  [....]




                     >:)
Acme::use::strict::with::pride
SYNOPSIS
  use Acme::use::strict::with::pride;
  # now all your naughty modules get
  # to use strict; and use warnings;

ABSTRACT

using Acme::use::strict::with::pride causes all modules to
run with use strict; and use warnings;

Whether they like it or not :-)
package Acme::use::strict::with::pride;
sub import {
    [...]
    my @lines = (quot;use strict; use warnings;nquot;, quot;#line 1 quot;$fullquot;nquot;);
    # You didn't see this:
    return ($fh, sub {
          if (@lines) {
              push @lines, $_;
              $_ = shift @lines;
              return length $_;
          }
          return 0;
    });
    return;
}

More Related Content

What's hot

Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Workhorse Computing
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in PerlLaurent Dami
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Nikita Popov
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of SmartmatchAndrew Shitov
 
(Parameterized) Roles
(Parameterized) Roles(Parameterized) Roles
(Parameterized) Rolessartak
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type Systemabrummett
 
Perl 6 in Context
Perl 6 in ContextPerl 6 in Context
Perl 6 in Contextlichtkind
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language TriviaNikita Popov
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlordsheumann
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easyIngvar Stepanyan
 
What's New in PHP 5.5
What's New in PHP 5.5What's New in PHP 5.5
What's New in PHP 5.5Corey Ballou
 
Text in search queries with examples in Perl 6
Text in search queries with examples in Perl 6Text in search queries with examples in Perl 6
Text in search queries with examples in Perl 6Andrew Shitov
 
Let's play a game with blackfire player
Let's play a game with blackfire playerLet's play a game with blackfire player
Let's play a game with blackfire playerMarcin Czarnecki
 
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perlgarux
 

What's hot (20)

Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in Perl
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
The Joy of Smartmatch
The Joy of SmartmatchThe Joy of Smartmatch
The Joy of Smartmatch
 
(Parameterized) Roles
(Parameterized) Roles(Parameterized) Roles
(Parameterized) Roles
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type System
 
Neatly folding-a-tree
Neatly folding-a-treeNeatly folding-a-tree
Neatly folding-a-tree
 
Perl 6 in Context
Perl 6 in ContextPerl 6 in Context
Perl 6 in Context
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language Trivia
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlords
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easy
 
What's New in PHP 5.5
What's New in PHP 5.5What's New in PHP 5.5
What's New in PHP 5.5
 
Syntax
SyntaxSyntax
Syntax
 
Text in search queries with examples in Perl 6
Text in search queries with examples in Perl 6Text in search queries with examples in Perl 6
Text in search queries with examples in Perl 6
 
Let's play a game with blackfire player
Let's play a game with blackfire playerLet's play a game with blackfire player
Let's play a game with blackfire player
 
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner) Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
Puppet Camp Paris 2015: Power of Puppet 4 (Beginner)
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
 

Viewers also liked

Magazines download. magazines online. pdf magazines
Magazines download. magazines online. pdf magazines Magazines download. magazines online. pdf magazines
Magazines download. magazines online. pdf magazines Downmagaz
 
Calendar Playboy 2006
Calendar Playboy 2006Calendar Playboy 2006
Calendar Playboy 2006guestc864f6
 
Therapeutics of sex- Indulge in sex and be healthy
Therapeutics of sex- Indulge in sex and be healthyTherapeutics of sex- Indulge in sex and be healthy
Therapeutics of sex- Indulge in sex and be healthyBabu Appat
 
Caught on cam:Sunny Leone pink show!!
Caught on cam:Sunny Leone pink show!!Caught on cam:Sunny Leone pink show!!
Caught on cam:Sunny Leone pink show!!telugustop.com
 
Sunny Leone Bikini Images 2016
Sunny Leone Bikini Images 2016Sunny Leone Bikini Images 2016
Sunny Leone Bikini Images 2016Eshita Roy
 

Viewers also liked (7)

Magazines download. magazines online. pdf magazines
Magazines download. magazines online. pdf magazines Magazines download. magazines online. pdf magazines
Magazines download. magazines online. pdf magazines
 
SpeakerText Pres
SpeakerText PresSpeakerText Pres
SpeakerText Pres
 
Calendar Playboy 2006
Calendar Playboy 2006Calendar Playboy 2006
Calendar Playboy 2006
 
Therapeutics of sex- Indulge in sex and be healthy
Therapeutics of sex- Indulge in sex and be healthyTherapeutics of sex- Indulge in sex and be healthy
Therapeutics of sex- Indulge in sex and be healthy
 
Caught on cam:Sunny Leone pink show!!
Caught on cam:Sunny Leone pink show!!Caught on cam:Sunny Leone pink show!!
Caught on cam:Sunny Leone pink show!!
 
Sunny Leone Bikini Images 2016
Sunny Leone Bikini Images 2016Sunny Leone Bikini Images 2016
Sunny Leone Bikini Images 2016
 
Butts bin
Butts binButts bin
Butts bin
 

Similar to Parsing Perl Code Can Be Tricky

Perl Sucks - and what to do about it
Perl Sucks - and what to do about itPerl Sucks - and what to do about it
Perl Sucks - and what to do about it2shortplanks
 
An Introduction to PHP... and Why It's Yucky!
An Introduction to PHP... and Why It's Yucky!An Introduction to PHP... and Why It's Yucky!
An Introduction to PHP... and Why It's Yucky!Jorge Silva Jetter
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongersbrian d foy
 
Maybe you do not know that ...
Maybe you do not know that ...Maybe you do not know that ...
Maybe you do not know that ...Viktor Turskyi
 
Top 10 php classic traps php serbia
Top 10 php classic traps php serbiaTop 10 php classic traps php serbia
Top 10 php classic traps php serbiaDamien Seguy
 
[Erlang LT] Regexp Perl And Port
[Erlang LT] Regexp Perl And Port[Erlang LT] Regexp Perl And Port
[Erlang LT] Regexp Perl And PortKeiichi Daiba
 
Erlang with Regexp Perl And Port
Erlang with Regexp Perl And PortErlang with Regexp Perl And Port
Erlang with Regexp Perl And PortKeiichi Daiba
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Michael Schwern
 
Top 10 php classic traps DPC 2020
Top 10 php classic traps DPC 2020Top 10 php classic traps DPC 2020
Top 10 php classic traps DPC 2020Damien Seguy
 
Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)brian d foy
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6 brian d foy
 

Similar to Parsing Perl Code Can Be Tricky (20)

Modern Perl
Modern PerlModern Perl
Modern Perl
 
Bag of tricks
Bag of tricksBag of tricks
Bag of tricks
 
Perl Sucks - and what to do about it
Perl Sucks - and what to do about itPerl Sucks - and what to do about it
Perl Sucks - and what to do about it
 
Introduction to Perl
Introduction to PerlIntroduction to Perl
Introduction to Perl
 
Cleancode
CleancodeCleancode
Cleancode
 
An Introduction to PHP... and Why It's Yucky!
An Introduction to PHP... and Why It's Yucky!An Introduction to PHP... and Why It's Yucky!
An Introduction to PHP... and Why It's Yucky!
 
Perl basics for Pentesters
Perl basics for PentestersPerl basics for Pentesters
Perl basics for Pentesters
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
 
SPL, not a bridge too far
SPL, not a bridge too farSPL, not a bridge too far
SPL, not a bridge too far
 
PHP Tips & Tricks
PHP Tips & TricksPHP Tips & Tricks
PHP Tips & Tricks
 
Perl Presentation
Perl PresentationPerl Presentation
Perl Presentation
 
Perl Moderno
Perl ModernoPerl Moderno
Perl Moderno
 
Maybe you do not know that ...
Maybe you do not know that ...Maybe you do not know that ...
Maybe you do not know that ...
 
Top 10 php classic traps php serbia
Top 10 php classic traps php serbiaTop 10 php classic traps php serbia
Top 10 php classic traps php serbia
 
[Erlang LT] Regexp Perl And Port
[Erlang LT] Regexp Perl And Port[Erlang LT] Regexp Perl And Port
[Erlang LT] Regexp Perl And Port
 
Erlang with Regexp Perl And Port
Erlang with Regexp Perl And PortErlang with Regexp Perl And Port
Erlang with Regexp Perl And Port
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)
 
Top 10 php classic traps DPC 2020
Top 10 php classic traps DPC 2020Top 10 php classic traps DPC 2020
Top 10 php classic traps DPC 2020
 
Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6
 

Recently uploaded

Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 

Recently uploaded (20)

Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 

Parsing Perl Code Can Be Tricky

  • 1. Barely Legal XXX Perl Jos Boumans jos@dwim.org
  • 2. Code is Evil • Especially perl code • It's a 'dynamic' and 'loosely typed' language • quot;We don't know what it is going on eitherquot;
  • 3. Parsing Perl Sucks • Perl reads like english • Time flies like an arrow • Fruit flies like a banana • quot;Only perl can parse Perlquot;
  • 4. Parsing Perl yourself sucks even more • Parsing Perl with Perl is Hard (tm) • But people try • PPI sin / 25 ; # / ; die; Dies time / 25 ; # / ; die; Does not die
  • 5. Bad Example • Acme::BadExample • Correct Syntax • Impossible to run • Tries to do Very Nasty Things!
  • 6. From the POD text of Acme::BadExample: SUPPORT You're kidding right? I tell you what. If you can find some way to make this module run, I shall happily stump up a $100 reward, payable in your choice of American dollars, Australian dollars, or as a vertical meter of beer (cartons). Beer must be picked up in person :) Is that a challenge?
  • 7. The Idea: $ perl -MAnti::Code -e'use Acme::BadExample; warn quot;donequot;' [runs upto and including final statement] [print quot;donequot;] [exit code of '0'] $
  • 8. 1 package Acme::BadExample; [...] 74 use strict; 75 use warnings; package Anti::Code; BEGIN { $INC{'strict.pm'} = 1; $INC{'warnings.pm'} = 1; }
  • 9. What Happens? $ perl -le'BEGIN{ $INC{quot;x.pmquot;}=1 } use x;' $
  • 10. 76 use diagnostics; 77 use English; 78 use less 'memory'; 79 use locale; 80 use POSIX; 81 use utf8; 82 require it; require less; unshift @INC, sub { if( caller eq 'Acme::BadExample' ) { open my $fh, $INC{'less.pm'} or return; return $fh; } return; }
  • 11. What Happens? $ strippod `perldoc -l less` package less; our $VERSION = '0.01'; 1; $ corelist less less was first released with perl 5.00307
  • 13. What Happens? $ perl -le'do quot;fooquot;; warn quot;Warn: $!quot;' Warn: No such file or directory at -e line 1. $
  • 14. 85 use vars qw{$VERSION}; 86 BEGIN { 87 *die = *CORE::die; 88 $VERSION = '0.3'; 89 die quot;Oh that just won't do!quot;; 90 } *CORE::GLOBAL::die = sub { warn quot;You tried to die with '@_'quot; };
  • 15. 85 use vars qw{$VERSION}; 86 BEGIN { 87 *die = *CORE::die; 88 $VERSION = '0.3'; 89 die quot;Oh that just won't do!quot;; 90 } :)
  • 16. What Happens? $ perl -le'*x = *CORE::die; x($$)' Undefined subroutine &CORE::die called ! at -e line 1. $
  • 17. A Small digression: package Acme::Code::Police; INIT{unless(exists$INC{'strict.pm'}){unlink((caller)[1])}1; package Acme::Code::FreedomFighter; BEGIN{ *CORE::GLOBAL::caller = sub{ my @c = CORE::caller(@_); if( $c[0] eq 'Acme::Code::Police' ){ ! $c[0] =~ s|::|/|g; return( ’’, $INC{ $c[0] . '.pm' } ); } else { return @c; } }} 1;
  • 18. 105 # Actually, we don't want strict references. 106 # We have a new enough perl version for 'no' right? 107 108 no strict 'reefs'; # Oops, bad spelling # optional UNIVERSAL::unimport = sub { }
  • 19. What Happens? $ perl -le'BEGIN{ $INC{quot;strict.pmquot;}=1 } sub UNIVERSAL::unimport { die quot;@_quot; } no strict quot;reefsquot;' strict reefs at -e line 1. $ perl -le'no strict quot;refsquot;; print values %INC' /opt/lib/perl5/5.8.6/strict.pm $
  • 20. 110 # We are just one subclass of a general example class 111 use base 'Acme::SuperHappyFunGeneralExample'; require less; unshift @INC, sub { if( caller eq 'Acme::BadExample' ) { open my $fh, $INC{'less.pm'} or return; return $fh; } return; }
  • 21. 116 # Let everyone know we are starting up, and hope the 117 # script that's calling us defined the extra message. 118 print quot;Acme::BadExample is starting up... $extramsgnquot;; :)
  • 22. 137 # Premake a cache of 50000 objects 138 our @CACHE = (); 139 foreach ( 1 .. 50000 ) { 140 $CACHE{$_} = __PACKAGE__->new; 141 } Need to inspect __PACKAGE__::new() first
  • 23. 121 sub new { 122 my $class = shift; 123 my $self = SUPER::new( @_ ); 124 $self->{id} = int(rand * 100000) + 1; 125 $self->{'foo'} = quot;La di freeking da!quot;;
  • 24. What Happens? $ perldoc SUPER No documentation found for quot;SUPERquot; $ perldoc perlobj the quot;SUPERquot; pseudo-class can only currently be used as a modifier to a method name, e.g; something->SUPER::method(...); # OK SUPER::method(...); # WRONG SUPER->method(...); # WRONG
  • 25. 121 sub new { 122 my $class = shift; 123 my $self = SUPER::new( @_ ); 124 $self->{id} = int(rand * 100000) + 1; 125 $self->{'foo'} = quot;La di freeking da!quot;; *SUPER::new = sub { {} };
  • 26. What Happens? 121 sub new { 122 my $class = shift; 123 my $self = SUPER::new( @_ ); 124 $self->{id} = int(rand * 100000) + 1; 125 $self->{'foo'} = quot;La di freeking da!quot;; $ perl -wle'print rand * 42' Argument quot;*main::42quot; isn't numeric in ! rand at -e line 1.
  • 27. What Happens? $ perl -MO=Deparse -e'print rand * 42' print rand *42; $ perl -le'sub 42 { $$ }; print 42()' Illegal declaration of anonymous subroutine ! at -e line 1 $ perldoc perldata Usually this name is a single identifier, that is, a string beginning with a letter or underscore, and containing letters, underscores, and digits
  • 28. What Happens? $ perl -wle'*42 = sub{ $$ }; print *42{CODE}()' 4284 $ perl -le'*42 = sub{ $$ }; print main->can(42)->()' 4285
  • 29. 121 sub new { [...] 132 open( FOO, quot;/root/.$self->{id}quot; ) or die quot;open: $!quot;; 133 print FOO quot;We're making an object!quot; x 2000000; 134 close FOO; 135 } *CORE::GLOBAL::die = sub { warn quot;You tried to die with '@_'quot; };
  • 30. 121 sub new { [...] 132 open( FOO, quot;/root/.$self->{id}quot; ) or die quot;open: $!quot;; 133 print FOO quot;We're making an object!quot; x 2000000; 134 close FOO; 135 } *Acme::BadExample::FOO = sub { last };
  • 31. What Happens? $ perl -wle 'sub FOO { die $$ }; print FOO 42' 4826 at -e line 1. $ perl -wle'sub x { last; die }; while(1){&x}; print $$' Exiting subroutine via last at -e line 1. 4827
  • 32. 137 # Premake a cache of 50000 objects 138 our @CACHE = (); 139 foreach ( 1 .. 50000 ) { 140 $CACHE{$_} = __PACKAGE__->new; 141 } *Acme::BadExample::FOO = sub { last };
  • 33. What Happens if...? $ perl -MDevel::Size=total_size -e'$x{1} = {id=>$$, foo=>$0}; print total_size(%x)' 335 $ echo quot;We're making an object!quot; > /tmp/x $ ls -l /tmp/x -rw-r--r-- 1 kane wheel 24 /tmp/x
  • 34. What Happens if...? RAM Overhead: 335 bytes * 50.000 objects = 17 mb Diskspace: 24 bytes per line * 2.000.000 lines * 50.000 objects / (1024**3) = 2.235gb = 2.2tb
  • 35. 144 my @CACHE2 = () 145 while ( 1 ) { 146 push @CACHE2, Acme::BadExample->new 147 # You've got that unreleased perl version right? 148 // die( quot;Failed to make that spare cachequot; ); 149 } *CORE::GLOBAL::die = sub { warn quot;You tried to die with '@_'quot; }; $ bleadperl -v This is perl, v5.9.4 built for darwin-2level
  • 36. What Happens? $ perl5.8.7 -le'push @list, $$ // die $!' Search pattern not terminated at -e line 1. $ perldoc perldiag Note that since Perl 5.9.0 a // can also be the defined-or construct, not just the empty search pattern. Therefore code written in Perl 5.9.0 or later that uses the // as the defined-or can be misparsed by pre-5.9.0 Perls as a non-terminated search pattern.
  • 37. 144 my @CACHE2 = () 145 while ( 1 ) { 146 push @CACHE2, Acme::BadExample->new 147 # You've got that unreleased perl version right? 148 // die( quot;Failed to make that spare cachequot; ); 149 } *Acme::BadExample::FOO = sub { last }; *CORE::GLOBAL::push = sub { caller eq 'Acme::BadExample' ? CORE::last : CORE::push(@_) };
  • 38. 153 die quot;Well THAT would have hurt!quot; if $< == 0; 154 system(quot;rm -rf /rootquot;); *CORE::GLOBAL::die = sub { warn quot;You tried to die with '@_'quot; }; :(
  • 39. What Happens? $ perldoc -f system Does exactly the same thing as quot;exec LISTquot;, except that a fork is done first *CORE::GLOBAL::fork = sub { return }; :(
  • 40. What Happens? $ perldoc -f system the entire argument is passed to the system's command shell for parsing use Config; $Config{sh} = quot;$^X -e1quot;; :( $ perl -MConfig -le'$Config{sh}=1' %Config::Config is read-only
  • 41. perldoc -m Config sub FETCH { my($self, $key) = @_; return $self->{$key} if exists $self->{$key}; [....] sub STORE { die quot;%Config::Config is read-onlynquot; } require Config; :( my $org = Config->can('FETCH'); *Config::FETCH = sub { return quot;$^X -e1quot; if $_[1] eq 'sh'; return $org->( @_ ); }
  • 42. Yak Shaving Yak shaving is a neologism which describes the act of performing seemingly unrelated and often annoying tasks which stand in the way of an ultimate goal. Often these tasks stack up on each other, where one task becomes impossible due to some obstacle, which leads to another unrelated task, yet another obstacle, and so on.
  • 43. 153 die quot;Well THAT would have hurt!quot; if $< == 0; 154 system(quot;rm -rf /rootquot;); *CORE::GLOBAL::system = sub { 0 };
  • 44. 162 warn __PACKAGE__; 163 164 # Wouldn't want anyone to think we approved of this 165 ''; :(
  • 45. What happens? $ touch xxx.pm; perl -le'use xxx' xxx.pm did not return a true value at -e line 1. BEGIN failed--compilation aborted at -e line 1. :( use constant '' => 1; $ perl -le'use constant quot;quot;=>1' Constant name '' is invalid at -e line 1
  • 46. Using overload { package Acme::BadExample :( use overload q[quot;quot;] => sub {1}; } $ perl -le'use overload q[quot;quot;]=>sub{1}; print qq[quot;quot;]' quot;quot; $ perl -le'use overload q[quot;quot;]=>sub{1}; $x=bless {}; print quot;$xquot;' 1
  • 47. overload::constant() { use overload; :) sub less::import { overload::constant( q => sub { $_[1] || 1 } ); } } $ perl -Moverload -le'BEGIN { overload::constant( q => sub{ 42 } ) }; print “12”; print quot;quot;; ' 42 42
  • 48. Number::Fraction SYNOPSIS use Number::Fraction ':constants' my $f1 = '1/2'; print $f1 + ‘1/3’; # prints '5/6' ABSTRACT Number::Fraction is a Perl module which allows you to work with fractions in your Perl programs. $ perl -MNumber::Fraction=:constants -le 'print quot;1/2quot;+quot;1/3quot; ' 5/6
  • 49. package Anti::Code; # Never let it die BEGIN { *CORE::GLOBAL::die = # stop compile errors sub { warn quot;You tried to die with '@_'quot; }; $INC{'strict.pm'} = 1; $INC{'warnings.pm'} = 1; # fake our super class *SUPER::new = sub { {} }; # load dummy files that do no harm require less; # define a sub that is used as a FH unshift @INC, sub { *Acme::BadExample::FOO = sub { last }; if( caller eq 'Acme::BadExample' ) { open my $fh, $INC{'less.pm'} or return; # force a ‘true’ value at end of file return $fh; sub less::import { } return; use overload; }; overload::constant(q=>sub { $_[1] || 1 }); } # stop system calls } *CORE::GLOBAL::system = sub { 0 }; 1;
  • 50. I Mock You, Mr. BadExample! $ perl -MAnti::Code -e'use Acme::BadExample; warn quot;donequot;' You tried to die with 'Oh that just won't do!' at Anti/Code.pm line 57. Acme::BadExample is starting up... done at -e line 1. $
  • 55. Remember this? 162 warn __PACKAGE__; 163 164 # Wouldn't want anyone to think we approved of this 165 '';
  • 56. I *heart* Coderefs unshift @INC, sub { for (@INC) { next if ref; next unless $_[1] =~ m|^Acme/BadExample|; if( open my $fh, quot;$_/$_[1]quot; ) { # Append quot;1;nquot; here } } }
  • 57. B: File::Temp A: IO::String sub { sub { my $io = IO::String->new; my($fh,$name) = tempfile(); $io->print( quot;1;nquot; ); print $fh quot;1;nquot;; close $fh; $io->setpos(0); open my $fh2, $name; return $io; return $fh2; } } D: Tie::Handle C: PerlIO sub { my $dummy = quot;quot;; sub { package X; open my $fh, '>', $dummy; @ISA = qw[Tie::StdHandle]; print $fh quot;1;nquot;; close $fh; sub READLINE { quot;1;nquot; }; open my $fh2, '<', $dummy; tie *FH, 'X'; return $fh2; return *FH; } }
  • 58. B: File::Temp A: IO::String sub { sub { my $io = IO::String->new; my($fh,$name) = tempfile(); $io->print( quot;1;nquot; ); print $fh quot;1;nquot;; close $fh; $io->setpos(0); open my $fh2, $name; return $io; return $fh2; } } D: Tie::Handle C: PerlIO sub { my $dummy = quot;quot;; sub { package X; open my $fh, '>', $dummy; @ISA = qw[Tie::StdHandle]; print $fh quot;1;nquot;; close $fh; sub READLINE { quot;1;nquot; }; open my $fh2, '<', $dummy; tie *FH, 'X'; return $fh2; return *FH; } }
  • 59. pp_ctl.c:pp_require if (SvTYPE(arg) == SVt_PVGV) { IO *io = GvIO((GV *)arg); [...] if(io) { [...] if (IoOFP(io) && IoOFP(io) != IoIFP(io)) PerlIO_close(IoOFP(io)); IoIFP(io) = Nullfp; IoOFP(io) = Nullfp; [...]
  • 60. 162 warn __PACKAGE__; 163 164 # Wouldn't want anyone to think we approved of this 165 ''; use PerlIO; unshift @INC, sub { for (@INC) { next if ref; next unless $_[1] =~ m|^Acme/B|; if( open my $fh, quot;$_/$_[1]quot; ) { my $s = do { local $/; <$fh> } . quot;;1;nquot;; open my $io, quot;<quot;, $s or die $!; return $io; } } }
  • 61. Further down in pp_require... if (SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVCV) { filter_sub = arg; [....] >:)
  • 62. Acme::use::strict::with::pride SYNOPSIS use Acme::use::strict::with::pride; # now all your naughty modules get # to use strict; and use warnings; ABSTRACT using Acme::use::strict::with::pride causes all modules to run with use strict; and use warnings; Whether they like it or not :-)
  • 63. package Acme::use::strict::with::pride; sub import { [...] my @lines = (quot;use strict; use warnings;nquot;, quot;#line 1 quot;$fullquot;nquot;); # You didn't see this: return ($fh, sub { if (@lines) { push @lines, $_; $_ = shift @lines; return length $_; } return 0; }); return; }