【问题标题】:Regular expressions with validations in RoR 4RoR 4 中带有验证的正则表达式
【发布时间】:2013-07-19 13:04:16
【问题描述】:

有如下代码:

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?

这是什么意思?我该如何解决?

【问题讨论】:

  • 你试过/\.(gif|jpg|png)$/i吗?也许%r{} 在末尾添加了它自己的$
  • @Wukerplank 我不这么认为。 %r{\.(gif|jpg|png)$}i #=&gt; /\.(gif|jpg|png)$/i, %r{\.(gif|jpg|png)}i #=&gt; /\.(gif|jpg|png)/i.
  • 是的,但没有帮助
  • @wukerplank 我们为什么要猜测?在 ruby​​ 中,我们有 irb 来帮助我们确定:)
  • 你需要把png后面的$去掉,表示这是最后一项,用\z替换

标签: ruby-on-rails ruby activerecord


【解决方案1】:

^$行的开始行的结束 锚点。而\A\z 是永久字符串开始和字符串结束锚点。
看看区别:

string = "abcde\nzzzz"
# => "abcde\nzzzz"

/^abcde$/ === string
# => true

/\Aabcde\z/ === string
# => false

所以 Rails 告诉你,“你确定要使用 ^$ 吗?你不想使用 \A\z 代替吗?”

产生此警告here 的轨道安全问题更多。

【讨论】:

  • 修正不必要的口语
  • 解释了它的要求,但没有回答如何解决它。我想如果你想使用 ^ 和 $ 修复它的方法是在类的顶部添加 :multiline => true ?
  • @isimmons 通过添加:multiline =&gt; true,您只会修复警告说 Rails 你知道你在做什么。
  • 答案就在那里:它是使用 \A 和 \z 而不是 ^ 和 $ 因为在 Ruby 中,^ 和 $ 只匹配换行符而不是字符串的开头和结尾,这允许 javascript 漏洞利用通过测试。
【解决方案2】:

由于您的验证规则容易受到 javascript 注入的影响,因此引发此警告。

在您的情况下,\.(gif|jpg|png)$ 匹配到行尾。因此,您的规则将验证此值 pic.png\nalert(1); 为 true:

"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

阅读文章:

【讨论】:

  • 最好的,希望我们能把这个作为公认的答案。
【解决方案3】:

警告是告诉你像下面这样的字符串将通过验证,但它可能不是你想要的:

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 选项”)告诉您,如果您真的想要 ^$ 的行为,您可以简单地将警告通过:multiline 选项。

【讨论】:

  • 那么你把:multiline传到哪里去了?
【解决方案4】:

问题 regexp 不在设计中,而是在 config/initializers/devise.rb 中。变化:

# Regex to use to validate the email address
config.email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i

到:

# Regex to use to validate the email address
  config.email_regexp = /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\Z/i

【讨论】:

    【解决方案5】:

    如果Ruby想看到\z而不是$符号符号,为了安全起见,你需要把它给他,那么代码应该是这样的:

    validates :image_url, allow_blank: true, format: {with: %r{\.(gif|jpg|png)\z}i, message: 'URL must point to GIF, JPG, PNG.'}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-22
      • 2017-10-31
      相关资源
      最近更新 更多