Небольшая проблема с null filehandle в perl
Опубликовано 26.06.2013
Рассмотрим удобную и потому частоиспользуемую конструкцию <> (null filehandle), имитирующую аналогичную фичу из sed и awk, когда один и тот же код может использоваться для чтения из STDIN или из файлов, чьи имена переданы в аргументах командной строки. Такая же конструкция используется в однострочниках с опцией -n:
while(<>){ # do something with line chomp; print "got line: [$line]"\n; }
Проблема в том, что для открытия файлов perl использует встроенный оператор open в форме с двумя аргументами (например, open FH, "$file"
где имя файла содержит и режим доступа к нему). Если название файла содержит идентификатор режима доступа, интерпретируемый функцией open ("| cmd"
, "cmd |"
или
"> /path/to/file"
), то вместо чтения файла выполнится соответствующая команда или файл перезапишется. Так что если приведенный чуть выше код записать в файл под названием getline.pl и выполнить с аргументом "| rm -rf /"
, то произойдет сами понимаете что.
Выстрелить себе в ногу легко, еще проще этого избежать:
– использовать ключ -T
, запрещающий использовать непроверенные данные;
– использовать ключ -i .backup
, интерпретирующий все переданные аргументы как файлы;
– преобразовывать @ARGV перед обработкой файлов, как это сделано в ARGV::readonly;
– не использовать конструкцию while(<>)
в критичных скриптах;
– иногда перечитывать perlsec.
Такие дела.