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

Esteemed monks,

For quite some time I have had a variety of scripts doing file uploads from a variety of browsers. Today I ran into a problem when using AOL Explorer. This runmode is taken form a CGI::Application application, and I find that when I look at the value of  $filename at the end of the method, it has the FULL original file name including the Windoze path.

sub landingpage_template_upload_graphic { my $self = shift; my $page = $self->_gen_pgwrapper(); my $q = $self->query; $dir = "/home/finc/www/content/sts/images/campaigns/"; my $filename; my $filehandle; if ( $filename = $q->param('image') ) { if ( $filename =~ /^([\w-]+\.(jpg|gif|png|jpeg))$/ ) { $filehandle = $filename; $filename = $1; open( OP, ">$dir/$filename" ) or die "$!"; chmod 0777, "$dir/$filename"; binmode OP; my $buffer; my $bytesread; while ( $bytesread = read( $filehandle, $buffer, 1024 ) ) { print OP $buffer; } close $filehandle; } } #} $page->param( 'warning' => Dumper($q) . "\nName: $filename\nDirector +y: $dir\n" ); return $page->output(); }
Obviously I have to modify the REGEX I am using to clean up the filename, but how do I come up with one that will work for all browsers?

jdtoronto

Replies are listed 'Best First'.
Re: CGI upload script problem with Explorer.
by philcrow (Priest) on Jul 25, 2006 at 16:02 UTC
    I'd try File::Basename. It should handle all paths no matter what OS hosts the browser. I think it is a standard module.

    Phil

Re: CGI upload script problem with Explorer.
by eric256 (Parson) on Jul 25, 2006 at 17:42 UTC

    Ack!! I would recommend not letting the user specify the file in this way. In other words don't count on the browser to send you the name of the file. Idealy if they will be overwritting existing files give them a drop down box to choose file names from (key the file names to numbers, use the numbers to lookup the filename in the script so they can't hack the HTML and use any name they want.) I would be afraid to use any script that lets the user control which file is getting uploaded and would continualy be worried that someone could figure out a way around your regex and overwrite files you don't want them near. Am I paranoid? Damn straight I am. ;) Take it with a grain of salt but i would recommend not relying on the web browser sending a name of the file its sending, i'm not sure that they even have to in the spec.


    ___________
    Eric Hodges
Re: CGI upload script problem with Explorer.
by Ieronim (Friar) on Jul 25, 2006 at 17:53 UTC
    Generally it is a very bad idea to create a file basing on the name received from the upload field. If the possibility of overwriting files with 'same names' is necessary, i'd create a DBM file with names of uploaded files as keys and names of files on the server as values. The names of files on server could be e.g. generated with File::Temp. And you can add any extra logic on the stage of creating new keys in DB.

         s;;Just-me-not-h-Ni-m-P-Ni-lm-I-ar-O-Ni;;tr?IerONim-?HAcker ?d;print
      eric256 & Ieronim,

      Your point is well taken, this is an internal application residing on an intranet or available through a VPN. It is essentially a highly specialised content manager that gets a whole lot of input from the user and packages up TAR files to be uploaded from my app server to a staging server in an IBM/Webshpere/Java environment. We need to have continuity of names from the designers desktop all the way through production. I do, however, appreciate the suggestions. Thank you!

      jdtoronto

        So, if you are sure that your users won't put any funny characters in their filenames, just remove the caret character from the regex in your code. Different browsers set differen names for uploaded files, but all of them include the base name. If i'm not mistaken, [\w-.] cannot be a path separator on any system.

             s;;Just-me-not-h-Ni-m-P-Ni-lm-I-ar-O-Ni;;tr?IerONim-?HAcker ?d;print
Re: CGI upload script problem with Explorer.
by jfluhmann (Scribe) on Jul 26, 2006 at 14:05 UTC

    The regex I've used for file uploads is:

    # Remove the file path information, if needed if ( $file =~ /([^\/\\]+)$/ ) { $filename = $1; # Set the filename } else { $filename = $file; }

    Hope that helps,
    Jeremy