基本的には、上記の両方の方法を使用main
して、文字列()が別の文字列()で始まるかどうかを確認したいと思いsub
ます。たとえば、私のコードは次のとおりです。
main = gets.chomp
sub = gets.chomp
p main.start_with? sub
p main[/^#{sub}/]
そして、これがI / Oの例です-オンラインで試してみてください!
単純な文字列を入力すると、どちらもまったく同じように機能"1\2"
しますが、のように文字列を入力するとstdin
、TIOの例に示すように、正規表現バリアントでエラーが発生します。
これは、2番目に渡された文字列が生ではないためだと思います。だから、私はsub.dump
2番目のものに渡してみました-オンラインで試してみてください!
それは私にnil
結果を与えます。これを正しく行う方法は?
原則として、信頼できないソースからの入力を盲目的に実行してはなりません。
信頼できない入力をaにRegexp
補間することは、たとえば、に補間することほど悪くはありません。Kernel#eval
攻撃者がaRegexp
で実行できる最悪のことは、正規表現のサービス拒否(ReDoS)攻撃を実行するためにEvil Regexを構築することです(上のセクションパフォーマンスでドキュメントが)、とのに対し、彼らは/ PIIとexfiltrateを含むがこれらに限定されない、ファイルシステム全体を削除する、暗号化されていないパスワード/クレジットカード情報のためのメモリをスキャンし、任意のコードを実行する可能性があり、そのネットワークを経由して、などRegexp
eval
しかし、それはまだ悪い考えです。たとえば、私はにはバグが存在しないことを前提とし、「起こる最悪の事態がReDoSである」と言ったときにRegexp
(実施Onigmoの場合はYARV、ジョニの場合はJRubyとTruffleRubyはRubyのなど、)Regexp
sは非常に強力であるため、Onigmo、Joniなど。は大きくて複雑なコードであり、特別に細工されたによって使用される可能性のある独自のセキュリティホールがある可能性がありますRegexp
。
あなたは適切にサニタイズし、ユーザー入力をエスケープする必要があります前に構築しますRegexp
。ありがたいことに、Rubyコアライブラリには、まさにそれを実行するメソッドがすでに含まれていますRegexp::escape
。したがって、次のようなことができます。
p main[/^#{Regexp.escape(sub)}/]
使用しようとしてもString#dump
うまくいかなかった理由String#dump
はString
、String
リテラルとして記述しなければならないのと同じ方法で表現するためです。つまりString
、メタ文字ではなくRegexp
メタ文字をエスケープし、String
その周りに引用符を含めます。String
リテラルとして認識させる必要があります。試してみると、簡単にわかります。
sub.dump
#=> "\"1\\\\2\""
# equivalent to '"1\\2"'
つまり、それは String#dump
Regexp
エスケープする必要があるという理由だけでエスケープする必要のない文字をエスケープし、String
#
"
String
秒(例えば[
、.
、?
、*
、+
、^
、-
)。この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加