Gisle Aas wrote:

>>Originally:
>>    142                  require Symbol;
>>    143                  my $fh = Symbol::gensym();
>>    144                  open($fh, $file) or Carp::croak("Can't open
>>file $file: $!");
>>    145                  binmode($fh);
>>
>>After changes:
>>
>>    142                  require Symbol;
>>    143                  my $fh = Symbol::gensym();
>>    144                  open($fh, '<', $file) or Carp::croak("Can't
>>open file $file: $!");
>>    145                  binmode($fh);
>>
>>Opening files with chars in filename like [\r<>\t], among others,
>>with 2 arguments raises the exception. With three arguments issues
>>are gone. More information on Perl Cookbook 7.2
> 
> 
> Only problem here is that this breaks compatibility with perl-5.005,
> which LWP still claims to support.

There are some other differences between these two code fragments than that the
second allows filenames with funky characters.

1.
If you are allowing other people to pass the filename into your program the
first should make you very concerned.  If that filename is as follows:

    $file = "cat /etc/passwd |";

then in standard two-argument open, without specifying a mode, this runs the
shell command and pipes the result to your program.  The shell command given can
be more destructive if you like.

If you're ensuring that pipe characters are not allowed in your filenames then a
filename of "> /etc/passwd" will suffice to clobber the /etc/passwd file anyway
(depending on privileges).

The second code fragment looks for a file of the exact name given.  It is
unlikely that a file named "cat\ /etc/passwd\ \|" will exist in your given
directory.

2.
The former code allows laziness on behalf of the programmer.  If the filename
provided contains spaces at the start or end such as:

    $file = "   /tmp/1234.txt";

    or

    $file = "/tmp/1234.txt   \n";

then Perl will ignore the extra whitespace characters and open the file called
"/tmp/1234.txt".  The new code will look for a file with the whitespace
characters embedded into it.

Please note that such a change is likely to break a lot of existing programs
which read in a filename from somewhere and then don't chomp it.


A backwards compatible solution which probably doesn't solve the problems in
point 2, but does solve the big problems in point 1 is to use sysopen:

    142               require Symbol;
    143               my $fh = Symbol::gensym();
                      use Fcntl qw/O_RDONLY/;
    144               sysopen($fh, $file, O_RDONLY) or Carp::croak("Can't
open file $file: $!");
    145               binmode($fh);

Trimming whitespace from the start and end of the filename will keep
compatibility with the previous version.

All the best,

        Jacinta

-- 
   ("`-''-/").___..--''"`-._          |  Jacinta Richardson         |
    `6_ 6  )   `-.  (     ).`-.__.`)  |  Perl Training Australia    |
    (_Y_.)'  ._   )  `._ `. ``-..-'   |      +61 3 9354 6001        |
  _..`--'_..-_/  /--'_.' ,'           | [EMAIL PROTECTED] |
 (il),-''  (li),'  ((!.-'             |   www.perltraining.com.au   |


Reply via email to