diff options
author | rabbit+bugs@rabbit.us <rabbit+bugs@rabbit.us> | 2008-10-05 21:19:10 -0700 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2008-10-19 12:04:31 +0000 |
commit | e55c0a828f279342571a887d09d7309727bcde4a (patch) | |
tree | ae219a78088527047581e84818c79859b3cf9c41 /lib | |
parent | 486bcc50ba13b9bb0f294f39e26e6e0d78f5f1fe (diff) | |
download | perl-e55c0a828f279342571a887d09d7309727bcde4a.tar.gz |
[perl #59650] File::Copy does not handle file objects sanely
From: "rabbit+bugs@rabbit.us (via RT)" <perlbug-followup@perl.org>
Message-ID: <rt-3.6.HEAD-29762-1223291950-1373.59650-75-0@perl.org>
Suggested change modified to cope with the hoop-jumping needed to keep
File::Copy working whilst bootstrapping the core build.
Some tests by me, to try to ensure that (arguablly buggy) IO::Scalar
will still work.
p4raw-id: //depot/perl@34519
Diffstat (limited to 'lib')
-rw-r--r-- | lib/File/Copy.pm | 19 | ||||
-rwxr-xr-x | lib/File/Copy.t | 48 |
2 files changed, 61 insertions, 6 deletions
diff --git a/lib/File/Copy.pm b/lib/File/Copy.pm index b6a05bae0e..9597264310 100644 --- a/lib/File/Copy.pm +++ b/lib/File/Copy.pm @@ -14,13 +14,17 @@ use File::Spec; use Config; # During perl build, we need File::Copy but Fcntl might not be built yet my $Fcntl_loaded = eval q{ use Fcntl qw [O_CREAT O_WRONLY O_TRUNC]; 1 }; +# Similarly Scalar::Util +# And then we need these games to avoid loading overload, as that will +# confuse miniperl during the bootstrap of perl. +my $Scalar_Util_loaded = eval q{ require Scalar::Util; require overload; 1 }; our(@ISA, @EXPORT, @EXPORT_OK, $VERSION, $Too_Big, $Syscopy_is_copy); sub copy; sub syscopy; sub cp; sub mv; -$VERSION = '2.13'; +$VERSION = '2.14'; require Exporter; @ISA = qw(Exporter); @@ -62,11 +66,16 @@ sub _catname { } # _eq($from, $to) tells whether $from and $to are identical -# works for strings and references sub _eq { - return $_[0] == $_[1] if ref $_[0] && ref $_[1]; - return $_[0] eq $_[1] if !ref $_[0] && !ref $_[1]; - return ""; + my ($from, $to) = map { + $Scalar_Util_loaded && Scalar::Util::blessed($_) + && overload::Method($_, q{""}) + ? "$_" + : $_ + } (@_); + return '' if ( (ref $from) xor (ref $to) ); + return $from == $to if ref $from; + return $from eq $to; } sub copy { diff --git a/lib/File/Copy.t b/lib/File/Copy.t index a6fa3cfb89..fc1f860a64 100755 --- a/lib/File/Copy.t +++ b/lib/File/Copy.t @@ -14,7 +14,7 @@ use Test::More; my $TB = Test::More->builder; -plan tests => 91; +plan tests => 136; # We're going to override rename() later on but Perl has to see an override # at compile time to honor it. @@ -289,6 +289,52 @@ SKIP: { ! -e $_ or unlink $_ or die $! for $src, $copy1, $copy2, $copy3; } +{ + package Crash; + # a package overloaded suspiciously like IO::Scalar + use overload '""' => sub { ${$_[0]} }; + use overload 'bool' => sub { 1 }; + sub new { + my ($class, $name) = @_; + bless \$name, $class; + } + + package Zowie; + # a different package overloaded suspiciously like IO::Scalar + use overload '""' => sub { ${$_[0]} }; + use overload 'bool' => sub { 1 }; + sub new { + my ($class, $name) = @_; + bless \$name, $class; + } +} +{ + my $object = Crash->new('whack_eth'); + my %what = (plain => "$object", + object1 => $object, + object2 => Zowie->new('whack_eth'), + object2 => Zowie->new('whack_eth'), + ); + + my @warnings; + local $SIG{__WARN__} = sub { + push @warnings, @_; + }; + + foreach my $left (qw(plain object1 object2)) { + foreach my $right (qw(plain object1 object2)) { + @warnings = (); + $! = 0; + is eval {copy $what{$left}, $what{$right}}, 1, "copy $left $right"; + is $@, '', 'No croaking'; + is $!, '', 'No system call errors'; + is @warnings, 1, 'Exactly 1 warning'; + like $warnings[0], + qr/'$object' and '$object' are identical \(not copied\)/, + 'with the text we expect'; + } + } +} END { 1 while unlink "file-$$"; |