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

I'm new to Perl programming, but I want to write a cgi script that creates a file based on the user's form input. The file name will be assigned by the variable $computer which is taken from the form input. $file = "data/$computer.txt"; If you entered cheese, $file should be equal to data/cheese.txt Unfortunately, no matter what happens, $file is equal to data/$computer.txt - literally. How do i fix this?

Replies are listed 'Best First'.
RE: string combinations
by jbert (Priest) on Feb 07, 2000 at 16:27 UTC
    prompt> perl $foo = "cheese"; $bar = "stuff/$foo.txt"; print "Bar is [$bar]\n"; ^D Bar is [stuff/cheese.txt]
    As someone else mentioned. The difference is in the quoting. Single quotes don't interpret variables in the string. Double quotes do.
    prompt> perl $foo = "cheese"; $bar = 'stuff/$foo.txt'; print "Bar is [$bar]\n"; ^D Bar is [stuff/$foo.txt]
    As the same person mentioned, you need to be careful with the characters which follow the variable name (the .txt in the example above). If perl can tell that these aren't part of the variable name then all is well. If perl can't be sure where your variable name finishes then you need to write the variable as ${foo}.
    $bar = "stuff/$foo1234"; # Bad $bar = "stuff/${foo}1234"; # Good
    And the real reason I added this bit:

    BE VERY CAREFUL WRITING CGI SCRIPTS! DON'T USE DATA FROM USERS WITHOUT CHECKING/SANITISING IT!

    Sorry for shouting, but bad things can happen. Please read the 'perlsec' page from the perl documentation before writing CGI scripts which might be accessed by anyone apart from yourself and close friends :-)

    Read up on the taint option (-T) which you can put on the #! line of your script (even on Windows...:-)

    What if the user entered a filename of "../../../../../etc/passwd" (not much in most setups, but you get the idea of one way in which a malicious user can attack an insecure script).

    There are lots of perl modules and pieces of advice on how to write good CGI scripts. Don't be scared off practicing with CGI but please don't put publically visible scripts up without decent security checking unless you don't mind losing your data and possibly everyone else's on the same server as you.

    Have a nice day ;-)

RE: string combinations
by xeh007 (Sexton) on Feb 07, 2000 at 04:54 UTC
    I would suggest trying: $file = 'data/' . $computer . '.txt';
Re: string combinations
by IndyZ (Friar) on Feb 07, 2000 at 06:31 UTC
    You should be able to do it with:
    $computer =~ /\.\.\///; $computer = "data/$computer.txt";
    That weird regular expression keeps people from from hoping out of your directory structure by inserting "../". Also, taint mode will give you hell if you try this with it turned on.
Re: string combinations
by stephen (Priest) on Feb 07, 2000 at 09:04 UTC
    I'm going to make a zen answer to this one: why do you want to do this? My guess is that you're using some user input to make unique file names. I'd instead recommend that you use a sequential numbering system (have a file that contains a single number, then increment-- you'll have to do file locking, but there'll be a good learning opportunity there) and use a database or DBM file to track the username/whatever text they entered. That way you get to bypass the tainting problems, and make sure that people can't overwrite other people. Of course, depends on your application.

    As for precisely what's going on in your script, the only likely explanation I can think of is that you're using single quotes. Or, try surrounding your scalar variable with braces: "dir/${computer}.txt".

    Good luck.