In The double diamond, a more secure <>, I showed how the diamond operator treated some characters as special when it tried to open the filenames in
@ARGV. I used a file name that ended with a
| to read the output for an external command.
Thinking about it more, I realized the problem is even worse. Opening an external command to read the output might even be useful. What if I start the filename with
> to open a file for writing, but not only writing, to truncate it to?
$ perl while.pl '> goodbye.txt'
That’s what happens. Something that should only read files can open them for writing. It can’t write anything to them with just that, but data still disappear. It can also make filenames appear, which might affect tests with the
-e file test operator.
Now, if someone can figure out how to make
ARGV the default filehandle, there could be real trouble. That’s easy enough to do by loading a module, even by adding something like
There are more games I can play. If I use the
perl normally takes the name of the input file and renames it (perhaps as a backup file by appending the value of
-i switch). It opens that renamed file for reading and opens a new file with the original name for writing.
I’ll try that by simply adding
-i to the previous command line:
$ perl -i while.pl while.pl '> test.txt' Can't open > test.txt: No such file or directory at while.pl line 5, <> line 5.
It doesn’t work! It looks for a file literally named > test.txt, which isn’t there. Well, it’s not there until I make it be there:
$ perl while.pl while.pl '> > test.txt' Can't open > test.txt: No such file or directory at while.pl line 5, <> line 5.
I’ll try again:
$ perl -i while.pl while.pl '> test.txt'
There’s no error this time, but I’m still not writing anything. I need to add the
-p switch to make
ARGVOUT the default output handle:
$ perl -pi while.pl while.pl '> test.txt'
But, that just sits there. Still, there might be other tricks that can come into play. That’s how these things work: you find one little thing and build on it.