in reply to Uploading and NT

You use binmode() on the output file but you forgot to use binmode() on the input file. Or at least it seems to me. Either your code is incomplete or you aren't even opening $file for reading. I hope the code is incomplete, because it couldn't have worked under UNIX in this form either, as read() takes a filehandle as the first parameter and not a filename. Also, it's not necessary to use binmode() on an opened filehandle more than once before closing it.

Update : In the context of a CGI script, the filename of the uploaded file might or might not contain the full (local) path to the uploaded file. In fact, it might contain the full path to the remote file, like c:\program files\test.txt, which was where the file resided on the user machine. Also, I fixed some type globs (note the asterisk before the file handles)

Here is some code that should work on any platform, and which should also be reasonably secure against users supplying malicious filenames to trick your http server into doing stuff (I hope) :

#!/usr/bin/perl -w use strict; use HTML::Entities; local *INFILE; local *OUTFILE; my $uploadedfilename = ""; # fill this in my $fullfilename = "D:/inetpub/general/nt/cv"; # This is the name we echo back to the user : my $htmlfilename = encode_entities($uploadedfilename); die "Upload temp file $htmlfilename not found !\n" unless -x $uploaded +filename; open INFILE, "< $uploadedfilename" or die "Opening the temp file $html +filename : $!\n"; binmode INFILE; open OUTFILE, "> $fullfilename" or die "Can't create $fullfilename : $ +!\n"; binmode OUTFILE; my ($bytesread, $buffer); while ($bytesread=read(INFILE,$buffer,1024)) { print OUTFILE $buffer; } close OUTFILE; close INFILE;

Update: If you are dealing with CGI.pm, the documentation mentions the following idiom, adapted to our needs, to handle uploaded files :

$fh = $query->upload('FILE1'); binmode $fh; while ($bytesread=read($fh, $buffer, 1024)) { print OUTFILE $buffer; }
This is the correct way and should be used. Using a string as a parameter to read() is allowed but deprecated.

Replies are listed 'Best First'.
RE: Re: Uploading and NT
by toadi (Chaplain) on Aug 16, 2000 at 15:55 UTC
    Update: Actually the most varations I tried should have worked. But I found out what the real problem was. In the filename I gave a concatenated the filename with a date/time stamp.Well in unix a : in a filename is no problem, well in NT it is. Problem solved, and concluded the most difficult problems are not the coding, but knowing what the Os specifics are.

    All by all a experience richer!


    Damn,
    I,m guilty of not testing code... This was an example. My code which I tested worked on linux.

    $basedir = "/home/geert/www/cv"; $onnum = 1; while ($onnum != 11) { $file = $req->param("FILE$onnum"); if ($file ne "") { $filename = $file; $filename =~ s!^.*(\\|\/)!!; open (OUTFILE, ">$basedir/$filename"); print "$basedir/$filename<br>"; while (my $bytesread = read($file, my $buffer, 1024)) { print OUTFILE $buffer; } close (OUTFILE); } $onnum++; }

    This worked, but it doesn't work on NT. And I used binmode...

    --
    My opinions may have changed,
    but not the fact that I am right