in reply to escaping filenames taken in via user input

This is what I would do:

my $filename = take_user_input(); $filename =~ s/\W//g; # allows only alphanumerics and the underscore $filename = $filename . ".txt"; # forces them to only open .txt files if (-T $filename) # checks to see if the file is a text file { open IN, "<", $filename or die &cant_open_file; print join "", <IN>; close IN; } else { &cant_open_file; }

Replies are listed 'Best First'.
Re^2: escaping filenames taken in via user input
by Aristotle (Chancellor) on Oct 30, 2002 at 00:57 UTC
    Minor nitpick for efficiency: don't do join '', <FH> - ever. Since you're only going to glue all the lines together anyway, don't ask for the file to be delivered line by line in the first place. Either localize $/ or use read. I'd do the first in this case.
    if(..) { open my $fh, "<", $filename or die &cant_open_file; local $/ = \8192; # read in 8 kbyte chunks rather than line by lin +e print while <$fh>; }
    See perldoc perlvar on the intricacies of $/. Note that this code uses a lexical to store the filehandle - it needs Perl 5.6 or newer to work that way, but affords us the luxury of not closing the file explicity. It just gets autoclosed when the $fh goes out of scope at the end of the block.

    Makeshifts last the longest.

      You would be correct. I didnt even notice the join. I just pasted that part <blushes>. Just focused on using the \W on the filename. Good point!
Re: Re: escaping filenames taken in via user input
by revdiablo (Prior) on Oct 30, 2002 at 02:18 UTC

    Escaping or removing all dots was something I originally considered, but decided against, because it would mangle my file exension. I didn't think to append the extension automatically... duh! How simple. :)

    Also, Aristotle++ for pointing out the problem with join "", <FH>. This is something I use often, for no reason other than it seems clear and obvious to me... but if it's grossly inefficient, I'll gladly switch to something else.

      Well, not necesarily grossly inefficient - but it's just useless work. I don't generally microoptimize, but there's absolutely no gain to be had by the less efficient form, since typing do { local $/; <FH> } instead takes no more programmer time and doesn't make maintenance any harder. So it's a case of simple economics. </rambling type="short"> :-)

      Makeshifts last the longest.