You finally are using strict and warnings. Those are at least two steps in the right direction.
Other monks have already mentioned that you need to read the documentation for CGI or switch to one of the modern frameworks. CGI spools uploaded files to temporary files before continuing your script; this is a possible DoS vector if a client uploads very large files. The temporary files are created and the upload accepted before your code gets a chance to check their sizes. There is another interface that allows you to process the uploaded data as it is received, avoiding this problem; you will need to read the CGI documentation for details.
You are not setting $allowed_size to a valid integer. An easy hint: integers do not require quotes in Perl. A much better way to represent 5MiB is 5 * (1<<20) or 5 * 1024 * 1024, depending on the familiarity of other programmers on the project with powers of two.
Your file-handling code makes no sense; read the documentation for rename and CGI. You are also printing (very confusingly) the name of the image to the output file, which is useless here.
While your use of for and last is clever, you really should use a single $status variable and a series of if or unless blocks. Something like:
my $status = ''; # note that '' is a false value
# ...
unless (image_has_good_type) {
$status = "bad image type";
}
unless ($status or image_not_empty) {
$status = "empty image";
}
unless ($status or image_too_long) {
$status = "image too long";
}
unless ($status) {
# accept upload
$status = "success";
}
# ...
print <<END_HTML;
# ...
<pre>$status</pre>
# ...
END_HTML
Using literal HTML in your script like that is also a recipe for confusing problems; you would do far better to put the HTML in a __DATA__ section and process it using Template::Toolkit or similar. The convention for here documents is for the end marker to read as an end marker; using START_HTML here is confusing. |