Все задачи

Валидация формы

11 Nov 2013
Read this article in English: here.

Программист оказался вовлечен в разработку веб-сервиса, на котором пользователи могут продавать и покупать подержанные книги. В частности, пользователь может ввести название и описание своей книги. Перед сохранением в БД данные формы валидируются такой функцией:

=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.

Правильные решения прислали наши читатели Кирилл и Тигран.