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

Hi there Monks!

I am having a problem with my code where I can not understand why the variable of the file handle is empty.
Here is where its happening:
#!/usr/bin/perl use strict ; use warnings ; use CGI ; use Net::FTP; my $cgi = CGI->new(); ... my $file_name = $cgi->param( 'doc' ) || ''; $cgi->upload( 'doc_upload' ); # Can I alter where the file is temporally written here? my $tmp_file = $cgi->tmpFileName( $file_name );
I'm using this code
warn qq{rename ("$tmp_file", "temp/$file_renamed");\n}; if (!rename("$tmp_file", "temp/$file_renamed" )) { warn $!, "\n"; } chmod 0664, "tmp/$file_renamed"; # Error: #Cannot open Local file doc1.txt: No such file or directory
to print what I am trying to rename to and I found that the "$tmp_file" is empty.
rename ("", doc1.txt");
When it should be printing something like this:

rename ("/tmp/967iaq5eJv", "doc1.txt");

My question is if there is a way to specify were the temp file handle gets written to instead of "/tmp".
At the end of the renaming of the file, I need to FTP this file and or course, it doesn't work because it cant find the file to use in "put".
... #my $put_file = $ftp->put("$file_renamed") or die "Cannot put file ", +$ftp->message; ... Error : Cannot put file The system cannot find the file specified.
I hope I could explain what is happening with the code and thanks a lot for looking at it!!!

Replies are listed 'Best First'.
Re: File upload with empty temp handle value
by Corion (Patriarch) on Jan 15, 2018 at 19:34 UTC

    Please do not let random uploaders from the outside give files names on your system.

    Ideally, you save the uploaded data to a file using a random name (or simply a number) and store the uploaded filename in a database together with the local name on your filesystem.

    The actual filename of your temporary upload file is available through the ->upload() and ->tmpFileName methods. But the CGI documentation shows their usage different from what you do:

    my $filehandle = $q->upload( 'uploaded_file' ); my $tmpfilename = $q->tmpFileName( $filehandle );

    Maybe if you adapt your code to use the functions as in the documentation it will work better?

    Personally, I would use File::Copy to copy data from the /tmp directory instead of hoping that rename will work.

    Maybe you will also find Text::CleanFragment helpful, which converts arbitrary text to ASCII without spaces, which is mostly harmless to use in filenames.

      "Please do not let random uploaders from the outside give files names on your system."
      This name "/tmp/967iaq5eJv" is not been assigned by the user, there is check in place for it, but its the value of this line of code:
      my $tmp_file = $cgi->tmpFileName( $file_name );
      I am trying to know why its empty. And if I could change its default to another location.

        Please re-read the documentation. You initialize $file_name from $cgi->param('doc');. The documentation of CGI initializes it from $cgi->upload(...). Maybe if you try that the name won't be empty.

        Later in your code, you are trusting that the user did not set the filename to something like ../remote-shell.php or even ./remote-shell.php. Giving users the ability to specify the content and the name of a file on your system is a really bad idea.