Регулярные выражения с проверками в RoR 4
есть следующий код:
class Product < ActiveRecord::Base
validates :title, :description, :image_url, presence: true
validates :price, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
validates :image_url, allow_blank: true, format: {
with: %r{.(gif|jpg|png)$}i,
message: 'URL must point to GIT/JPG/PNG pictures'
}
end
это работает, но когда я пытаюсь проверить его с помощью "rake test" я поймаю это сообщение:
rake aborted!
The provided regular expression is using multiline anchors (^ or $), which may present a security risk. Did you mean to use A and z, or forgot to add the :multiline => true option?
что это значит? Как я могу это исправить?
5 ответов:
^
и$
старт в строке и конец в строке якоря. В то время как\A
и\z
постоянный старт строки и конец строки якоря.
Смотрите разницу:string = "abcde\nzzzz" # => "abcde\nzzzz" /^abcde$/ === string # => true /\Aabcde\z/ === string # => false
Итак, Rails говорит вам: "вы уверены, что хотите использовать
^
и$
? Вы не хотите использовать\A
и\z
вместо этого?"есть еще на рельсах озабоченность безопасностью, которая генерирует это предупреждение здесь.
это предупреждение возникает, потому что ваше правило проверки уязвимо для инъекции javascript.
в вашем случае
\.(gif|jpg|png)$
матчи до конца строки. Поэтому ваше правило будет проверять это значениеpic.png\nalert(1);
а так:"test.png\n<script>alert(1)</script>" === /\.(gif|jpg|png)$/i # => true "test.png\n<script>alert(1)</script>" === /\.(gif|jpg|png)\z/i # => false
читать статей:
проблема regexp не в devise, а скорее живет в config/initializers/devise.рубидий. Изменение:
# Regex to use to validate the email address config.email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
to:
# Regex to use to validate the email address config.email_regexp = /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\Z/i
предупреждение говорит вам, что строки, подобные следующим, пройдут проверку, но это, вероятно, не то, что вы хотите:
test = "image.gif\nthis is not an image" re = /\.(gif|jpg|png)$/i re.match(test) #=> #<MatchData ".gif" 1:"gif">
и
^
и$
соответствует началу / концу любой строки, а не началу/концу строки.\A
и\z
соответствует началу и концу полной строки, соответственно.re = /\.(gif|jpg|png)\z/i re.match(test) #=> nil
вторая часть предупреждения ("или забыл добавить: multiline => true option") говорит вам, что если вы действительно хотите поведение
^
и$
вы можете просто заставить замолчать предупреждение, передавая .