Perl Переменные только для печати номинала сохраненных данных и регулярных выражений - PullRequest
1 голос
/ 12 ноября 2011

У меня есть вопрос о Perl из приведенного ниже сценария.Если для переменной $user введено значение joeshmo; ls -l;, perl выведет joeshmo только в том случае, если строка print $user закодирована.Моя интуиция подсказывает мне, что все joeshmo; ls -l; должны быть напечатаны.Однако, если пользовательская переменная указана на finger, который должен быть выполнен, выполняются и joeshmo, и ls -l.Я спрашиваю об этом, потому что я пытаюсь ограничить входные данные, разрешенные для переменной $user, с помощью выражения, подобного

if (($user !~ /^[a-z_A-Z0-9]+[-+%]*[a-z_A-Z0-9]+$/)){
die "The entered user name uses characters not of the alphanumeric form or the \"-\", \"+\", or \"%\"!";
}
else{

. В приведенном выше утверждении я считаю, что единственный ввод, который не приведет кdie - это операторы с буквенно-цифровыми символами и символом подчеркивания, за которым следуют символы -, +,% (если они есть), а затем еще один раунд буквенно-цифровых символов и знак подчеркивания.Однако регулярное выражение оценивает только первую часть переменной $user, а не всю, как в случае с вводом joeshmo; ls -l;.Регулярное выражение оценивается только на joeshmo.

Другая интересная информация, которую я не понимаю, - почему точки с запятой не отображаются при печати переменной $user?Если бы они были, я мог бы просто искать их, но они не напечатаны, и поэтому они не могут быть оценены по регулярному выражению.

Буду признателен за любую помощь по этим вопросам!

<code>#!/usr/bin/perl

use CGI;
use CGI::Carp qw(fatalsToBrowser);
$q = new CGI;

print $q->header,
    $q->start_html('Finger User'),
    $q->h1('Finger User');
print "<pre>\n";

$user = $q->param("user");
print "\n";
print $user;
print "\n\n";

if (($user !~ /^[a-z_A-Z0-9]+[-+%]*[a-z_A-Z0-9]+$/)){
die "The entered user name uses characters not of the alphanumeric form or the \"-\", \"+\", or \"%\"!";
}
else{
print `/usr/bin/finger -s $user`;
}

print "
"; напечатать $ q-> end_html;

1 Ответ

4 голосов
/ 13 ноября 2011

Я не думаю, что вы ls -l вообще получаете $user. Если бы это было так, то ваше регулярное выражение, которое лучше было бы записать как $user !~ /^\w+[-+%]*\w+$/, совпадало бы, и ваш die был бы выполнен. Я предполагаю, что вы называете этот скрипт как

/cgi-bin/something.pl?user=joeshmo; ls -l;

Некоторые реализации допускают использование точки с запятой (;) в качестве разделителя в строках запроса, так что приведенное выше (с некоторыми реализациями сервера) будет эквивалентно:

/cgi-bin/something.pl?user=joeshmo& ls -l&

и так, часть ls -l не будет считаться частью user. Попробуйте URL кодировки точек с запятой и пробелов:

/cgi-bin/something.pl?user=joeshmo%3B%20ls%20-l%3B

и тогда вы должны увидеть свой ls -l и вызвать die.

Причина, по которой ; иногда допускается в качестве разделителя, заключается в том, что & также используется HTML для кодирования объектов, поэтому любые амперсанды, которые появляются в атрибуте HTML, должны быть закодированы как &amp; или риск путаницы; например, это часто будет плохо вести себя:

<a href="http://example.com?a=b&reg=c">

но это не так:

<a href="http://example.com?a=b&amp;reg=c">

В спецификации HTML4 W3 рекомендует:

[...] что разработчики HTTP-серверов и, в частности, разработчики CGI поддерживают использование ";" вместо «&» избавить авторов от необходимости экранировать символы «&» таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...