Change 30322 by [EMAIL PROTECTED] on 2007/02/15 17:15:34

        Integrate:
        [ 28295]
        Subject: [PATCH lib/AutoLoader.pm lib/AutoLoader.t] Export can() with 
AUTOLOAD()
        From: chromatic <[EMAIL PROTECTED]>
        Date: Sat, 20 May 2006 11:40:27 -0700
        Message-Id: <[EMAIL PROTECTED]>
        
        With tweaks: use built-in ref() instead of Scalar::Util::blessed
        
        [ 29743]
        Subject: Bug in AutoLoader.pm causing endless loop
        From: Steffen Mueller <[EMAIL PROTECTED]>
        Date: Tue, 09 Jan 2007 19:15:36 +0100
        Message-ID: <[EMAIL PROTECTED]>
        
        [ 29750]
        Subject: [PATCH] AutoLoader fix, part 2
        From: Steffen Mueller <[EMAIL PROTECTED]>
        Date: Wed, 10 Jan 2007 18:52:23 +0100
        Message-ID: <[EMAIL PROTECTED]>
        
        [ 29934]
        Upgrade to AutoLoader-5.63

Affected files ...

... //depot/maint-5.8/perl/lib/AutoLoader.pm#3 integrate
... //depot/maint-5.8/perl/lib/AutoLoader.t#5 integrate

Differences ...

==== //depot/maint-5.8/perl/lib/AutoLoader.pm#3 (text) ====
Index: perl/lib/AutoLoader.pm
--- perl/lib/AutoLoader.pm#2~18080~     2002-11-03 21:23:04.000000000 -0800
+++ perl/lib/AutoLoader.pm      2007-02-15 09:15:34.000000000 -0800
@@ -15,11 +15,59 @@
     $is_epoc = $^O eq 'epoc';
     $is_vms = $^O eq 'VMS';
     $is_macos = $^O eq 'MacOS';
-    $VERSION = '5.60';
+    $VERSION = '5.63';
 }
 
 AUTOLOAD {
     my $sub = $AUTOLOAD;
+    my $filename = AutoLoader::find_filename( $sub );
+
+    my $save = $@;
+    local $!; # Do not munge the value. 
+    eval { local $SIG{__DIE__}; require $filename };
+    if ($@) {
+       if (substr($sub,-9) eq '::DESTROY') {
+           no strict 'refs';
+           *$sub = sub {};
+           $@ = undef;
+       } elsif ($@ =~ /^Can't locate/) {
+           # The load might just have failed because the filename was too
+           # long for some old SVR3 systems which treat long names as errors.
+           # If we can successfully truncate a long name then it's worth a go.
+           # There is a slight risk that we could pick up the wrong file here
+           # but autosplit should have warned about that when splitting.
+           if ($filename =~ s/(\w{12,})\.al$/substr($1,0,11).".al"/e){
+               eval { local $SIG{__DIE__}; require $filename };
+           }
+       }
+       if ($@){
+           $@ =~ s/ at .*\n//;
+           my $error = $@;
+           require Carp;
+           Carp::croak($error);
+       }
+    }
+    $@ = $save;
+    goto &$sub;
+}
+
+sub can {
+    my ($self, $method) = @_;
+
+    my $parent          = $self->SUPER::can( $method );
+    return $parent if $parent;
+
+    my $package         = ref( $self ) || $self;
+    my $filename        = AutoLoader::find_filename( $package . '::' . $method 
);
+    local $@;
+    return unless eval { require $filename };
+
+    no strict 'refs';
+    return \&{ $package . '::' . $method };
+}
+
+sub find_filename {
+    my $sub = shift;
     my $filename;
     # Braces used to preserve $1 et al.
     {
@@ -41,9 +89,11 @@
        if (defined($filename = $INC{"$pkg.pm"})) {
            if ($is_macos) {
                $pkg =~ tr#/#:#;
-               $filename =~ s#^(.*)$pkg\.pm\z#$1auto:$pkg:$func.al#s;
+               $filename = undef
+                 unless $filename =~ s#^(.*)$pkg\.pm\z#$1auto:$pkg:$func.al#s;
            } else {
-               $filename =~ s#^(.*)$pkg\.pm\z#$1auto/$pkg/$func.al#s;
+               $filename = undef
+                 unless $filename =~ s#^(.*)$pkg\.pm\z#$1auto/$pkg/$func.al#s;
            }
 
            # if the file exists, then make sure that it is a
@@ -52,15 +102,15 @@
            # (and failing) to find the 'lib/auto/foo/bar.al' because it
            # looked for 'lib/lib/auto/foo/bar.al', given @INC = ('lib').
 
-           if (-r $filename) {
+           if (defined $filename and -r $filename) {
                unless ($filename =~ m|^/|s) {
                    if ($is_dosish) {
                        unless ($filename =~ m{^([a-z]:)?[\\/]}is) {
-                            if ($^O ne 'NetWare') {
-                                       $filename = "./$filename";
-                               } else {
-                                       $filename = "$filename";
-                               }
+                           if ($^O ne 'NetWare') {
+                               $filename = "./$filename";
+                           } else {
+                               $filename = "$filename";
+                           }
                        }
                    }
                    elsif ($is_epoc) {
@@ -87,33 +137,7 @@
            $filename =~ s#::#/#g;
        }
     }
-    my $save = $@;
-    local $!; # Do not munge the value. 
-    eval { local $SIG{__DIE__}; require $filename };
-    if ($@) {
-       if (substr($sub,-9) eq '::DESTROY') {
-           no strict 'refs';
-           *$sub = sub {};
-           $@ = undef;
-       } elsif ($@ =~ /^Can't locate/) {
-           # The load might just have failed because the filename was too
-           # long for some old SVR3 systems which treat long names as errors.
-           # If we can successfully truncate a long name then it's worth a go.
-           # There is a slight risk that we could pick up the wrong file here
-           # but autosplit should have warned about that when splitting.
-           if ($filename =~ s/(\w{12,})\.al$/substr($1,0,11).".al"/e){
-               eval { local $SIG{__DIE__}; require $filename };
-           }
-       }
-       if ($@){
-           $@ =~ s/ at .*\n//;
-           my $error = $@;
-           require Carp;
-           Carp::croak($error);
-       }
-    }
-    $@ = $save;
-    goto &$sub;
+    return $filename;
 }
 
 sub import {
@@ -125,9 +149,11 @@
     #
 
     if ($pkg eq 'AutoLoader') {
-       no strict 'refs';
-       *{ $callpkg . '::AUTOLOAD' } = \&AUTOLOAD
-           if @_ and $_[0] =~ /^&?AUTOLOAD$/;
+       if ( @_ and $_[0] =~ /^&?AUTOLOAD$/ ) {
+           no strict 'refs';
+           *{ $callpkg . '::AUTOLOAD' } = \&AUTOLOAD;
+           *{ $callpkg . '::can'      } = \&can;
+       }
     }
 
     #
@@ -171,9 +197,12 @@
     my $callpkg = caller;
 
     no strict 'refs';
-    my $symname = $callpkg . '::AUTOLOAD';
-    undef *{ $symname } if \&{ $symname } == \&AUTOLOAD;
-    *{ $symname } = \&{ $symname };
+
+    for my $exported (qw( AUTOLOAD can )) {
+       my $symname = $callpkg . '::' . $exported;
+       undef *{ $symname } if \&{ $symname } == \&{ $exported };
+       *{ $symname } = \&{ $symname };
+    }
 }
 
 1;

==== //depot/maint-5.8/perl/lib/AutoLoader.t#5 (xtext) ====
Index: perl/lib/AutoLoader.t
--- perl/lib/AutoLoader.t#4~21850~      2003-12-05 11:44:34.000000000 -0800
+++ perl/lib/AutoLoader.t       2007-02-15 09:15:34.000000000 -0800
@@ -16,7 +16,7 @@
        unshift @INC, $dir;
 }
 
-use Test::More tests => 17;
+use Test::More tests => 22;
 
 # First we must set up some autoloader files
 my $fulldir = File::Spec->catdir( $dir, 'auto', 'Foo' );
@@ -74,18 +74,21 @@
 
 sub new { bless {}, shift };
 sub foo;
-sub bar;
 sub bazmarkhianish; 
 
 package main;
 
-my $foo = new Foo;
+my $foo = Foo->new();
 
 my $result = $foo->can( 'foo' );
 ok( $result,               'can() first time' );
 is( $foo->foo, 'foo', 'autoloaded first time' );
 is( $foo->foo, 'foo', 'regular call' );
 is( $result,   \&Foo::foo, 'can() returns ref to regular installed sub' );
+$result    = $foo->can( 'bar' );
+ok( $result,               'can() should work when importing AUTOLOAD too' );
+is( $foo->bar, 'bar', 'regular call' );
+is( $result,   \&Foo::bar, '... returning ref to regular installed sub' );
 
 eval {
     $foo->will_fail;
@@ -97,7 +100,7 @@
 
 # Used to be trouble with this
 eval {
-    my $foo = new Foo;
+    my $foo = Foo->new();
     die "oops";
 };
 like( $@, qr/oops/, 'indirect method call' );
@@ -118,7 +121,7 @@
 eval {
   $foo->blechanawilla;
 };
-like( $@, qr/syntax error/, 'require error propagates' );
+like( $@, qr/syntax error/i, 'require error propagates' );
 
 # test recursive autoloads
 open(F, '>', File::Spec->catfile( $fulldir, 'a.al'))
@@ -144,6 +147,7 @@
 package Bar;
 AutoLoader->import();
 ::ok( ! defined &AUTOLOAD, 'AutoLoader should not export AUTOLOAD by default' 
);
+::ok( ! defined &can,      '... nor can()' );
 
 package Foo;
 AutoLoader->unimport();
@@ -160,8 +164,21 @@
 
 ::is( Baz->AUTOLOAD(), 'i am here', '... but not non-imported AUTOLOAD()' );
 
+
+package SomeClass;
+use AutoLoader 'AUTOLOAD';
+sub new {
+    bless {} => shift;
+}
+
 package main;
 
+$INC{"SomeClass.pm"} = $0; # Prepare possible recursion
+{
+    my $p = SomeClass->new();
+} # <-- deep recursion in AUTOLOAD looking for SomeClass::DESTROY?
+::ok(1, "AutoLoader shouldn't loop forever if \%INC is modified");
+
 # cleanup
 END {
        return unless $dir && -d $dir;
End of Patch.

Reply via email to