Проблема с именем пути к файлу, возможные поврежденные символы
Perl и HTML, CGI в Linux. Проблема с именем пути файла, передаваемого в поле формы, в CGI на сервере. Проблема связана с путем к файлу Linux, а не с ПК.
Я использую 2 программы, 1) программу, написанную несколько лет назад, динамический HTML, созданный в Perl-программе и представленный пользователю в виде формы. Я изменил, вставив необходимый код, чтобы пользователь мог выбрать файл на своем ПК для размещения на компьютере с Linux.
Поскольку эта программа уже знала путь к файлу, необходимый на стороне Linux, я передаю этот путь к файлу в скрытом поле формы программе 2.
2) CGI-программа на стороне Linux, запускаемая при размещении формы в (1).
Странный вопрос. Путь к файлу, который я передаю, имеет очень странную проблему. Я могу извлечь это, используя
my $filepath = $query->param("serverfpath");
Вышеуказанное заполняет $filepath тем, что выглядит как правильный путь.
Но он терпит неудачу, и не таким образом, что приводит меня к блоку ошибок открытия файла, а так, что вызов сценария CGI дает ошибку.
Однако, если я наполнил $filepath ТОЧКО той же строкой, через жесткое кодирование, это сработает, и мой файл успешно загрузится.
Например:
$fpath1 = $query->param("serverfpath");
$fpath2 = "/opt/webhost/ims/DOCURVC/data"
Сравнение $fpath1 и $fpath2 показывает, что они в точности равны. Проверка длины $fpath1 и $fpath2 показывает, что они абсолютно одинаковой длины.
Я перепробовал много способов очистки данных в $fpath1. Я жму это. Я удаляю любые нестандартные символы.
$fpath1 =~ s/[^A-Za-z0-9\-\.\/]//g;
и это:
my $safe_filepath_characters = "a-zA-Z0-9_.-/";
$fpath1 =~ s/[^$safe_filepath_characters]//g;
Но что бы я ни делал, использование $fpath1 приводит к ошибке, использование $fpath2 работает.
Что может быть не так с данными в $fpath1, что может привести к тому, что они будут успешно сравниваться с $fpath2, но не будут равны, визуально выглядят абсолютно равными, будут иметь одинаковую длину, но не работать одинаково?
Для приведенного ниже файла откройте блок.
$upload_dir = $fpath1
вызывает полную неудачу загрузки CGI, как будто он не может найти CGI (что, как я знаю, иногда вызывается синтаксической ошибкой в скрипте CGI).
$uplaod_dir = $fpath2
Я получил успешную загрузку файла
$uplaod_dir = ""
Вызов cgi не завершается ошибкой, он выполняет блок else из приведенного ниже if, как и ожидалось.
вот блок открытия файла:
if (open ( UPLOADFILE, ">$upload_dir/$filename" ))
{
binmode UPLOADFILE;
while ( <$upload_filehandle> )
{
print UPLOADFILE;
}
close UPLOADFILE;
$msgstr="Done with Upload: upload_dir=$upload_dir filename=$filename";
}
else
{
$msgstr="ERROR opening for upload: upload_dir=$upload_dir filename=$filename";
}
Какие еще тесты я должен выполнить для $fpath1, чтобы выяснить, почему он не работает так же, как его жестко запрограммированный эквивалент $fpath2
Я пробовал замену символов, по одному символу за раз, от $fpath2 до $fpath1. Даже выполнение этого с одним символом приводило к тому, что $fpath1 имел ту же ошибку, что и $fpath2, хотя символ выглядел точно так же.
2 ответа
Ваш CGI, возможно, работает на Perl с -T
(режим порчи) (например, #!/usr/bin/perl -T
)? Если это так, любое значение, поступающее из ненадежных источников (таких как пользовательский ввод, URI и поля формы), не может использоваться в системных операциях, таких как open
до тех пор, пока он не будет обработан с помощью захвата регулярных выражений. Обратите внимание, что с помощью s///
изменить его на месте не приведет к отмене значения.
$fpath1 =~ /^([A-Za-z0-9\-\.\/]*)$/;
$fpath1 = $1;
die "Illegal character in fpath1" unless defined $fpath1;
Должен работать, если ваша проблема в режиме taint.
Но он терпит неудачу, и не таким образом, что приводит меня к блоку ошибок открытия файла, а так, что вызов сценария CGI дает ошибку.
Преждевременный конец заголовков скриптов? Попробуйте запустить CGI из командной строки:
perl your_upload_script.cgi serverfpath=/opt/webhost/ims/DOCURVC/data