Search code examples
perlfirefoxfileinput

Can Perl's CGI.pm process Firefox's <input type="file", multiple=""> form fields?


Firefox 3.6 introduced a [multiple attribute on regular type="file" input elements]( http://hacks.mozilla.org/2009/12/multiple-file-input-in-firefox-3-6/).

I cannot get Perl to process these fields. I can call the field in a list context like this:

 my @files = $CGIobject->param("File_Input");

Looping through that will give me the file names as strings but nothing else.

Any suggestions would be greatly welcome.

Here's the HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>

  <head>
    <title>Multiple file upload test</title>

  </head>

  <body>

    <form action="deliberately_obfuscated" 
          method="post" 
         enctype="multipart/form-data">

      <input type="file" 
             name="multiple_files" 
         multiple="true"/>

      <button type="submit">Submit</button>

    </form>

  </body>

</html>

Here is the Perl:

#!/usr/bin/perl

#use strict;
#use warnings;

use CGI;

my $CGIo = new CGI;

print $CGIo->header();

@lightweight_fh = $CGIo->upload('myfiles');

# undef may be returned 
# if it's not a 
# valid file handle

if (@lightweight_fh) {

  # Upgrade the handle to 
  # one compatible with IO::Handle:

  my $io_handle = $lightweight_fh->handle;

  open (OUTFILE,'>>','/hidden_deliberately/');

  while ($bytesread = $io_handle->read($buffer,1024)){

    print OUTFILE $buffer;

  }

}

The script does not enter the

if (@lightweight_fh) {

block.

I've tried Data:Dumper on @lightweight_fh before the if block and it literally prints absolutely nothing.


Solution

  • Woohoo, got this working. The big handbrake issue? Old CGI.pm version! It's a shame the CGI.pm documentation does not include notes alongside features such as "Introduced in version X". Many other modules/libraries/packages do.

    As it happens I had version 3.15 and the current is 3.49. I even got it working in strict mode. Anybody know why Stein uses non-strict examples?

    Here's the XHTML:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html>
    
      <head>
        <title>Multiple file upload test</title>
    
      </head>
    
      <body>
    
        <form action="deliberately_hidden"
              method="post"
             enctype="multipart/form-data">
    
          <input type="file"
                 name="multiple_files"
             multiple="true"/>
    
          <button type="submit">Submit</button>
    
        </form>
    
      </body>
    
    </html>
    

    Here's the Perl:

    #!/usr/bin/perl
    
      use strict;
      use warnings;
    
      use CGI;
    
      my $CGIo = new CGI;
    
      print $CGIo->header();
    
      my @lightweight_fh = $CGIo->upload('multiple_files');
    
      foreach my $fh (@lightweight_fh) {
    
        # undef may be returned if it's not a valid file handle
    
        if (defined $fh) {
    
          # Upgrade the handle to one compatible with IO::Handle:
    
          my $io_handle = $fh->handle;
    
          open (OUTFILE,'>>','/deliberately_hidden/' . $fh);
    
          while (my $bytesread = $io_handle->read(my $buffer,1024)) {
    
            print OUTFILE $buffer
    
          }
    
        }
    
      }
    

    Thanks for your help everyone.