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

I'm trying to write the contents of a file to a new file name. I know it should be easy but i'm having trouble with it. Any Idea's? -Lisa ;)
#!/usr/local/bin/perl print "Content-type: text/html\n\n"; use CGI; $q = new CGI; $A_file = $q->cookie('cookie_1'); $B_file = "file.txt"; open FILE, "$B_file"; $Data = <FILE>; close (FILE); open(OUT,">$A_file") or die $!; print OUT "$Data\n" or die $!; close(OUT) or die $!;

Replies are listed 'Best First'.
Re: Writing to a different file name
by Abigail-II (Bishop) on Dec 16, 2003 at 09:31 UTC
    This is a pretty dangerous thing you are doing. You retrieve the file name to be copied from a cookie - but the cookie is supplied by the client side. What if the cookie contains rm -rf / |?

    I would first check if what the cookie supplies is indeed a file, and a file that I'm allowed to copy, and then use

    system cp => $file1, $file2; die "Copy returned ", $? >> 8, "\n" if $?;
    to copy the file.

    Note that the way system is used is 'safe', there's no shell that will interpret funny characters.

    Abigail

      The open FOO, ">$file" syntax will not allow pipes, so there is no danger from "rm -rf / |".

      It will get messed up if $file starts with & or >, though. To prevent this, just switching to 3-arg open is sufficient: open FOO, ">", $file or bailout("error opening output file: $!")

Re: Writing to a different file name
by inman (Curate) on Dec 16, 2003 at 09:00 UTC
    You are openening a file that is named in a cookie. This means that a) The cookie needs to exist and b) it contains the correct file name relative to where your CGI app is running. You really need to do some checking to make sure that both of these requirements are met. This will involve you checking for the existence of the cookie, checking that the file name contained within it can be located and then opening.

    You should be aware that taking any value from the user and treating it as a file name is a huge security hole since the user could pass the name of a system file or device etc.

      Say the magic word. Say it.
      taint
      Thank you.

      To the OP: your data is tainted. Please untaint it.

Re: Writing to a different file name
by Anonymous Monk on Dec 16, 2003 at 08:17 UTC
    What errors do you get?
    Why not check open FILE, "$B_file"; for failure (it can fail just as easy as your attempt to write)?
    Why not use File::Copy?
Re: Writing to a different file name
by gjb (Vicar) on Dec 16, 2003 at 08:56 UTC

    One of the things that might go wrong is that you only read one line of $B_file, is this intensional?

    Another potential problem is that you don't strip line endings from the line you read (no chomp) but write a \n to the output file nevertheless, so you may have an end-of-line too many.

    And as pointed out above, the read operation might fail without you noticing since you don't check for errors after attempting to open $B_file.

    Hope this helps, but yes, mentioning what kind of problems you have might help you even more ;) -gjb-

Re: Writing to a different file name
by Hena (Friar) on Dec 16, 2003 at 09:06 UTC
    Whole file copying i suggest using File::Copy. Basicly you can do this.
    use File::Copy; $A_file = $q->cookie('cookie_1'); $B_file = "file.txt"; copy ($B_file,$A_file);
    Alternative way (probably slower though).
    open FILE, "$B_file" or die "Unable to open \'$B_file\': $!"; open(OUT,">$A_file") or die "Unable to open \'$A_file\': while (<FILE>) { print OUT "$_"; }
    Btw, if you want to remove old, then use rename command (instead of examples above).
      Thanx... did the trick. -Lisa
Re: Writing to a different file name
by Anonymous Monk on Dec 16, 2003 at 08:17 UTC
    I know it should be easy but i'm having trouble with it. Any Idea's? -Lisa ;)
    I've got a lot of ideas, but none more pervasive than "What trouble (yes, you should've learned by now to mentioned that first)?"