develooper Front page | perl.perl5.porters | Postings from February 2012

Re: [perl #111126] perlbug AutoReply: File::Spec copy() zeros filewhen copying a file into the same directory it is stored in.

Thread Next
From:
David Yingling
Date:
February 22, 2012 02:31
Subject:
Re: [perl #111126] perlbug AutoReply: File::Spec copy() zeros filewhen copying a file into the same directory it is stored in.
Message ID:
20120222023641.0b9d0f33.deeelwy@gmail.com
> On Wed, 22 Feb 2012 00:29:04 +1100, Tony Cook wrote:
> 
> Thank you for the report, but this change is wrong in several
> different ways:
> 
> a) it ignores that the file system could be case-insensitive
> 
> b) if $from includes a path component (eg "foo/bar.txt") the glob
> won't find that file if it is in "$to/foo/".
> 
> c) if $from contains regexp metacharacters (like '.') the matched
> filename won't necessarily be the same.
> 
> d) $from might be found internal to $to, eg. $from = "a", $to = "ab/".
> 
> e) it's horribly inefficient
> 
> and more I haven't expressed.
> 

I was short sighted, and only focused on making the test pass, and
nothing else. I didn't consider the big picture or any of those issues.

> I suspect a simpler fix would be to move the code:
> 
> if (!$from_a_handle && !$to_a_handle && -d $to && ! -d $from) {
> $to = _catname($from, $to);
> }
> 
> above the stat() checks. Or perhaps above the _eq() check.
> 

Below is a patch that does just what you suggested, and it makes the
test pass.

> --- /usr/lib64/perl5/5.12.3/File/Copy.pm        2011-01-26 13:52:24.000000000 -0500
> +++ lib/File/Copy.pm    2012-02-22 02:14:31.332547908 -0500
> @@ -145,6 +145,10 @@
>          return 1;
>      }
>  
> +    if (!$from_a_handle && !$to_a_handle && -d $to && ! -d $from) {
> +       $to = _catname($from, $to);
> +    }
> +
>      if ((($Config{d_symlink} && $Config{d_readlink}) || $Config{d_link}) &&
>         !($^O eq 'MSWin32' || $^O eq 'os2')) {
>         my @fs = stat($from);
> @@ -157,10 +161,6 @@
>         }
>      }
>  
> -    if (!$from_a_handle && !$to_a_handle && -d $to && ! -d $from) {
> -       $to = _catname($from, $to);
> -    }
> -
>      if (defined &syscopy && !$Syscopy_is_copy
>         && !$to_a_handle
>         && !($from_a_handle && $^O eq 'os2' )   # OS/2 cannot handle handles


> If it's essential to preserve the error messages then extra variables
> will be needed.
> 
> Tony

If you mean to imply that the change you suggested, and that I tried out in the patch above prevents the error message from being printed, it does not. Because the error message is *still* printed.

A debugging session revealed that the code you suggested I move cleans up copy()'s $to argument and turns it from ['.'] to ['./test_file'].

Because of this change the code that comes next that calls carp() with an error message actually does run properly, and carp() is called with an error message, and copy() returns 0 for failure.

Thanks,
Dave.

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About