読者です 読者をやめる 読者になる 読者になる

感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

Railsで「The provided regular expression is using multiline anchors (^ or $)」みたいなエラーが出た時。

Rails
<スポンサーリンク>

列車本の写経をしてvalidatesを書いているときに、以下のようなエラーが出た。

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?

これは、Rails4?から出るようになったらしい。
セキュリティを厳しくするためだそう。

解決策は色々と以下のStackOverFlowに書いてある。
http://stackoverflow.com/questions/17759735/regular-expressions-with-validations-in-ror-4

とりあえず、主な解決策は2つあるようで、
1つめは:multiline => true
を追加する。これはちょっと強引なやり方。

  validates :image_url, allow_blank: true, format: {
    with:    %r{\.(gif|jpg|png)$}i,
    message: 'はGIF、JPG、PNG画像のURLでなければなりません',
    :multiline => true
  }

もう一つは、"$"のところを\zに置き換える方法。

  validates :image_url, allow_blank: true, format: {
    with:    %r{\.(gif|jpg|png)\z}i,
    message: 'はGIF、JPG、PNG画像のURLでなければなりません',
    #:multiline => true
  }

なんでこんな風にしたというと、正規表現の穴をつかれるのを防ぐため。
StackOverFlowを見ると、$で終わっているときは、想定外なものと一致してしまう可能性がある。

string = "abcde\nzzzz"
# => "abcde\nzzzz"
/^abcde$/ === string
# => true

$はこういう意味。

正規表現の末尾にある $ は、入力文字列の末尾に一致します。たとえば、[0-9]$ と指定した場合、入力文字列の末尾にある数字に一致します。

だから、代わりに\z,\aとかを使って、

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

厳密に正規表現チェックしろよ、という意味。

\a 任意の英数字 : ([a-zA-Z0-9])
\z 整数 : ([0-9]+)

正規表現の参考
http://www.lightship.co.jp/FileVisor6/help/operation/regexp.htm

RailsによるアジャイルWebアプリケーション開発 第4版

RailsによるアジャイルWebアプリケーション開発 第4版

読んでいるのはコレ。
手元にあるポケットリファレンスと一緒に読むと理解が深まる。