とんちむ日記

RubyとJavaScriptと猫が好きです

Rubyの正規表現に潜む罠!!

現在のプロジェクトでmodelのバリデーションを正規表現で行う機会がありました。

Javascriptなんかでは最近よく触っていたので正規表現には特に抵抗なかったんですが・・・思わぬ罠に引っかかってしまいました。

例えばこんな /^[0-9]+$/ というようなよく見る整数の正規表現なんですが・・・このまま動かそうとすると例外発生!!

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?

まさか正規表現で例外がでるとは思ってなかったのでぽかんとしていました。

上記の意味ですが、「与えられた正規表現複数行アンカー(^か$)を使ってるからエラー出たよ、セキュリティ的な危険があるけど\A と\zを使うつもりだったのかそれとも複数行オプションをつけ忘れたのかい?」

まぁこんな感じです、てきとうな訳ですが細かいことは気にしない気にしない。

Rubyは他の言語と違い、改行を含んだ値が渡されると、その値のどこか一つの行にマッチすれば他は気にしないという謎仕様なのです。
^と$は通常は入力された値の全体の先頭と末尾を表しますが、Rubyの場合は若干異なり、行の先頭と末尾になるのです。

じゃあどうするかというと、メッセージどおりに^を\Aに$を\zに変更するだけでOKです。または multiline: trure をオプションで追加して

validates :hogehoge , format: { with:/^pattern$/, multiline: true }

とすればOKです。multilineオプションをつけることで他の言語と同じような挙動になります。


詳しくはRails セキュリティガイド の6.6正規表現に書いてあります。

皆さんもどうか罠には気を付けて…まぁそのままだと例外出るから大丈夫だろうけど。