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

I'm trying to build an upload script that only allows certain file types (doc, docx, odt, & rtf). The only problem is, the script uploads any file I give it, even if it's the wrong type.

Cutting out the irrelevant code, I have:

#!/usr/bin/perl -wT use strict; use CGI qw/param uploadInfo/; use CGI::Carp qw ( fatalsToBrowser ); use File::Basename; my $query = new CGI; my $filename = $query->param("manuscript"); my ( $name, $path, $extension ) = fileparse ( $filename, '\..*' ); $filename = $name . $extension; my @allowedext = qw(doc docx odt rtf); unless(@allowedext = $extension) { print $query->header ( ); print "Filetype not allowed. Please upload doc, docx, odt, or rtf fil +es only."; exit; }

Any ideas what I'm doing wrong?

Update: Oops, I guess I stripped out too much! In the full script, $name and $extension are initialized. Updated the code above to include it. The unless($allowedext{$extension}) was someone else's suggestion. It was originally unless($extension = @allowedext) I've changed and overwritten so much, I forgot that that piece of code didn't work. When running the script successfully, but without the extension check stopping the upload of an unacceptable filetype, I had resorted to the original piece of code, which is now reflected above.

Update 2: It ain't pretty, but I got it working. I still don't know what I couldn't get map to work on my webhost, but this gets around that issue.

if (lc $extension ne ("doc" "docx" or "odt" or "rtf")) { print "Filetype '$extension' not allowed. File extension must be: do +c, docx, odt, or rtf"; exit; }

Replies are listed 'Best First'.
Re: extension check on upload script doesn't do anything
by toolic (Bishop) on Feb 23, 2011 at 03:31 UTC
    When I try to compile your code at the command line, it complains very loudly:
    c:> perl -Tc 889712.pl Status: 500 Content-type: text/html <h1>Software error:</h1> <pre>Global symbol &quot;$name&quot; requires explicit package name at + 889712.pl line 11. Global symbol &quot;$extension&quot; requires explicit package name at + 889712.pl line 11. Global symbol &quot;%allowedext&quot; requires explicit package name a +t 889712.pl line 15. Global symbol &quot;$extension&quot; requires explicit package name at + 889712.pl line 15. 889712.pl had compilation errors. </pre> <p> For help, please send mail to this site's webmaster, giving this error + message and the time and date of the error. </p> [Tue Feb 22 22:34:08 2011] 889712.pl: Global symbol "$name" requires e +xplicit package name at 889712.pl line 11. [Tue Feb 22 22:34:08 2011] 889712.pl: Global symbol "$extension" requi +res explicit package name at 889712.pl line 11. [Tue Feb 22 22:34:08 2011] 889712.pl: Global symbol "%allowedext" requ +ires explicit package name at 889712.pl line 15. [Tue Feb 22 22:34:08 2011] 889712.pl: Global symbol "$extension" requi +res explicit package name at 889712.pl line 15. [Tue Feb 22 22:34:08 2011] 889712.pl: 889712.pl had compilation errors +.
    You are using strict (as you should), but you need to declare and initialize all your variables ($name, $extension). You created an array variable (@allowedext), but then tried to access it as if it were a hash.

    See also Troubleshooting Perl CGI scripts

Re: extension check on upload script doesn't do anything
by toolic (Bishop) on Feb 23, 2011 at 15:30 UTC
    I realize this still does not answer your main question, but your updated code probably does not do what you want:
    unless(@allowedext = $extension)
    That is an assignment, whereas you probably wanted some kind of comparison. You clobber all elements of the array, then set the array to a single value. Since the assignment is (probably) always successful, you never enter the unless clause. I think you really want a hash like GrandFather suggested.
      toolic, Thanks for the explanation. I'm still very to to Perl (obviously), coming from a background in VB. Your explanation tells me why the script doesn't complain about an improper filetype.

      As I mentioned to GrandFather, when I substituted his code into my script, it just creates a 500 error. I've been reading the perldoc for map, plus tutorials on PM and elsewhere. I'm at a loss. It works at the command line, but when I upload it to my host, it 500's.

Re: extension check on upload script doesn't do anything
by GrandFather (Saint) on Feb 23, 2011 at 03:32 UTC

    You can't just invent stuff and expect it to work! The code as posted doesn't compile for a couple of reasons:

    • Neither $name nor $extension are declared
    • $allowedext{$extension} implies there is a %allowedext variable, but there is none such.

    I'd clean the code up by doing something like:

    my @okTypes = qw(doc docx odt rtf); my %allowedext = map {$_ => 1} @okTypes; if (!$allowedext{lc $extension}) { print "Filetype '$extension' not allowed. File extension must be one + of ", join ', ', @okTypes; exit; }
    True laziness is hard work
    A reply falls below the community's threshold of quality. You may see it by logging in.