正規表現を使用して任意の長い入力文字列からキーと値のペアを抽出し、繰り返しパターンの長い文字列に対してスタックオーバーフローが発生するケースを実行しています。出力のJavaパターンでスタックオーバーフローが発生する
public static void parse(String input)
{
String KV_REGEX = "((?:\"[^\"^ ]*\"|[^=,^ ])*) *= *((?:\"[^\"]*\"|[^=,^\\)^ ])*)";
Pattern KV_PATTERN = Pattern.compile(KV_REGEX);
Matcher matcher = KV_PATTERN.matcher(input);
System.out.println("\nMatcher groups discovered:");
while (matcher.find())
{
System.out.println(matcher.group(1) + ", " + matcher.group(2));
}
}
いくつかの架空の例:
String input1 = "2012-08-09 09:10:25,521 INFO com.a.package.SomeClass - Everything working fine {name=CentOS, family=Linux, category=OS, version=2.6.x}";
String input2 = "2012-08-09 blah blah 09:12:38,462 Log for the main thread, PID=5872, version=\"7.1.8.x\", build=1234567, other=done";
がparse(input1)
を呼び出し生成:
{name, CentOS
family, Linux
category, OS
version, 2.6.x}
がparse(input2)
を呼び出し生成:
はKV-解析するコードは次のようになります
これは問題ありません(最初のケースでは少しの文字列処理が必要です)。文字列がここに置くためには長すぎる
Exception in thread "main" java.lang.StackOverflowError
at java.util.regex.Pattern$BitClass.isSatisfiedBy(Pattern.java:2927)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
...
を、それ以下の例外を除いて、前述のクラスのオーバーフローが発生し、非常に長い(1,000文字)クラスパス文字列を解析しようとしたときただし、(スタート)以下、簡単に再現可能と繰り返し構造を有する:問題を再現したい
java.class.path=/opt/files/any:/opt/files/any:/opt/files/any:/opt/files/any
誰もがちょうど上記の文字列に:/opt/files/any
数十回を追加する必要があります。クラスパス文字列に ":/ opt/files/any"が約90個コピーされた文字列を作成すると、スタックオーバーフローが発生します。
上記のKV_REGEX
文字列を変更できるという一般的な方法があるため、問題は発生せず、同じ結果が生成されますか?
パーズする前に最大の文字列の長さをチェックする(たとえば)ハックとは対照的に、上記のジェネリックを明示的に指定します。
私が思い付くことができる最も総修正、真のアンチパターンは、Funnily十分
public void safeParse(String input)
{
try
{
parse(input);
}
catch (StackOverflowError e) // Or even Throwable!
{
parse(input.substring(0, MAX_LENGTH));
}
}
あり、それは私がそれを試してみましたいくつかの実行で動作しますが、それはお勧めするのに十分な味わい深いものではありません。 :-)
制限を破りましたことをお祝いします。 – kosa
ありがとう!私はいつでも報酬のための解決策を受け入れるだろう! :-)限界が壊れていたのは何ですか? – PNS
この部分は何と一致するはずですか?それはまったく正しいとは思わない。 '[^ =、^ \\)^]'。 – Keppil