http://www.perlmonks.org?node_id=776463

citromatik has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

I have encountered a code like this in a production program I couldn't make run:

use strict; use warnings; my $ref_file = $ARGV[0]; if (isReadableFile ($ref_file)) { executeComm ("cat $ref_file"); } else { print STDERR "$ref_file Does not exist\n"; } ## In a different module... sub isReadableFile { my $file = shift; if (defined ($file) && # was a file name passed? ((-f $file) || (-l $file)) && # is the file a file or sym. link +? (-r $file) # is the file readable? ) { return 1; } else { return 0; } } sub executeComm { my ($comm) = @_; print "$comm\n"; system ($comm); print "$?\n"; }

A sample invocation should be something like:

$ perl test.pl file.txt

And if file.txt exists, is a regular file or links to a file and is readable, the command cat file.txt is executed inside the executeComm sub.

The problem arises when the file name or its path contains spaces:

$ perl test.pl file\ name.txt

This should be a valid invocation, but executeComm will receive the command cat file name.txt, and consequently, will fail. The same would happen if $ perl test.pl 'file name.txt' is passed, and perl test.pl 'file\ name.txt' would succeed, but the file tests on isReadableFile fail

A possible patch would be to escape every space after the file tests:

if (isReadableFile ($ref_file)) { $ref_file =~ s/ /\\ /g; ###### Added executeComm ("cat $ref_file"); } else { print STDERR "$ref_file Does not exist\n"; }

But this seems a weak patch... Is this solution portable? Do you anticipate the appearance of more problems?, how would you solve this in production code?

citromatik