Программист оказался вовлечен в разработку веб-сервиса, на котором пользователи могут продавать и покупать подержанные книги. В частности, пользователь может ввести название и описание своей книги. Перед сохранением в БД данные формы валидируются такой функцией:
=head2 validate_form
Валидация формы:
* длина полей не должна превышать ограничений
* во всех полях должны использоваться только разрешенные символы
Функция возвращает '', если все хорошо, и код первой обнаруженной проблемы иначе.
=cut
{
my %LIMIT = (
author => 100,
title => 150,
description => 2000,
);
sub validate_form
{
my ($form) = @_;
for my $f (qw/author title description/){
# строка не слишком длинная
return "TOO_LONG_FIELD_".uc($f) if length($form->{$f}) > $LIMIT{$f};
# строка состоит только из разрешенных символов
return "DISALLOWED_SYMBOLS_IN_FIELD_".uc($f) unless $form->{$f} =~ /[-_a-zа-я0-9\.,:!?;'"()\+ ]+/i;
}
return '';
}
}
Однако спустя некоторое время программист обнаруживает в базе данных неправильные данные. Например, в поле “description” некоторых книг встречаются html-теги, которые не должны бы проходить валидацию…
Была у программиста проблема, решил он использовать регулярные выражения. Теперь у программиста две проблемы ^_^
Проблема в сравнении $form->{$f} =~ /[-_a-zа-я0-9\.,:!?;'"()\+ ]+/i
.
Оператор m//
– это поиск подстроки, удовлетворяющей заданному регулярному выражению.
Поэтому если в строке встречается хотя бы один разрешенный символ – проверка разрешает эту строку.
Как минимум, стоило бы указать начало и конец строки в регулярном выражении:
/^[-_a-zа-я0-9\.,:!?;'"()\+ ]+$/i
.
Правильные решения прислали наши читатели Кирилл и Тигран.