in reply to CGI-Upload / Bad File Number

Hi,

thanks for your suggestions.

'$src' contains the name of the file to be uploaded (i.e. '123.jpg'). The value comes from a html-formular.

I want to upload a file, so - as far as i know - i don't have to open it and there is no handle. But i have to admit, that i don't really aunderstand how uploading-process works.

As alredy mentioned, i use a simelar code in another script, where it works fine. Below is the working function (comments are translated) for comparation...

if($file=~/[\w _\.\-\(\)\+]+\.jpg/i) { # --- Zieldateiennamen erstelle und Datei öffnen => engl.: c +reate destination-file-name and open $sname = time.'.'.$ENV{'REMOTE_ADDR'}.' - '.$ueberschrift.' - '. +$unterschrift.' - '.$file; $sname =~ s/ä/ae/g; $sname =~ s/Ä/Ae/g; $sname =~ s/ö/oe/g; $sname =~ s/Ö/Oe/g; $sname =~ s/ü/ue/g; $sname =~ s/Ü/Ue/g; $sname =~ s/ß/ss/g; $fname = '../Content/Gaestebuch/'.$sname; open DAT,'>'.$fname or die 'Error processing file: ',$!; # --- Dateien in den Binaer-Modus schalten => engl.: switc +h to bin-mode binmode $file; binmode DAT; # --- Datei hochladen => engl.: Upload my $data; while(read $file,$data,640000) { print DAT $data; } close DAT; }

As you see, also here '$file' (= '$src' in the other function) is not a handle.

Replies are listed 'Best First'.
Re^2: CGI-Upload / Bad File Number
by poj (Abbot) on Jul 16, 2016 at 16:14 UTC
    i don't really understand how uploading-process works.

    If you using CGI, see CGI, in particular the section on Older ways to process uploads

    The original way to process file uploads with CGI.pm was to use param(). The value it returns has a dual nature as both a file name and a lightweight filehandle.
    

    You should find your working script will fail if you force $file into scalar by adding the line

    if($file=~/[\w _\.\-\(\)\+]+\.jpg/i) { $file = ''.$file;

    Does $src have some added processing that $file doesn't. ?

    poj

      This is how i read the CGI-data:

      $query = new CGI; @names = $query->param; foreach (@names) { $val = $query->param($_); eval("\$$_ += '$val';"); }

      There is one value called '$file1' containing the source-file.

      The upload-function is called this way:

      if ($FNC eq "Hochladen") { if ($file1 ne "") { Upload("$DIR$FIL +E/_file1", $file1); } }
      ...where '$file1' is named '$src' in the function and "$DIR$FILE/_file1" is the destination filename without extension, which is taken from the source filename.

      There is no other apperence of '$file1' or '$src' in my code.

        I would remove the eval , like this

        my $query = new CGI; my $file1 = $query->param('file1'); if ($query->param('FNC') eq "Hochladen") { if ($file1 ne "") { Upload("$DIR$FILE/_file1", $file1); } }

        If would help to see the complete cgi script as I suspect some other improvements could be suggested.

        poj

        This is security hole, anybody running your cgi can run any perl program they write    eval("\$$_ = '$val';");        }

        $cgi->param already gives you access to params by name, there is no need for eval

        If you want something other than $cgi use a hash, see CGI->VarsAsHash