Web page file upload is always corrupted

121 views Asked by At

I am trying to add a file upload to an existing web page.

Every time I upload I get a file that is corrupted.

I made sure to set binmode on the file handle. I also have my input enctype set to multipart/formdata in my form.

My code is as follows

$article{upload_file_name} = $cgi->param( 'upFile' );
$article{upload_file}      = $cgi->upload( 'upFile' );

if ( $article{upload_file_name} ne "" or $article{upload_file_name} ne null ) {

    open( UPLOADS, ">$uploads_dir/$article{upload_file_name}" )
            or die "Could not open $uploads_dir/$article{upload_file_name}";

    binmode UPLOADS;

    while ( <$article{upload_file}> ) {
        print UPLOADS;
    }

    close UPLOADS;
}

I also tried this

$article{upload_file} = $cgi->param( 'upFile' );

if ( $article{upload_file} ne "" or $article{upload_file} ne null ) {

    open( UPLOADS, ">$uploads_dir/$article{upload_file}" )
            or die "Could not open $uploads_dir/$article{upload_file}";
    binmode UPLOADS;

    while ( <$article{upload_file}> ) {
        print UPLOADS;
    }

    close UPLOADS;
}
1

There are 1 answers

5
mob On BEST ANSWER
<$article{upload_file}>

is not doing what you think it is doing. The diamond operator (<>) is used to stand in for Perl's readline function, but it has a second meaning where it does the same thing as Perl's glob function. And in Perl's parsing rules, <$hash{key}> is always treated as glob.

perldoc -f perlop explains:

If what's within the angle brackets is neither a filehandle nor a simple scalar variable containing a filehandle name, typeglob, or typeglob reference, it is interpreted as a filename pattern to be globbed, and either a list of filenames or the next filename in the list is returned, depending on context. This distinction is determined on syntactic grounds alone. That means <$x> is always a readline() from an indirect handle, but <$hash{key}> is always a glob(). That's because $x is a simple scalar variable, but $hash{key} is not--it's a hash element. Even <$x > (note the extra space) is treated as glob("$x "), not readline($x).

There are at least a couple of workarounds:

  1. Use explicit readline call:

    while (readline($article{upload_file}))
    
  2. Assign filehandle to a simple scalar

    my $upload_fh = $article{upload_file};
    ...
    while (<$upload_fh>)