もう一度、正規表現、バックトラック、および2行の「無害な」コードをJVMブレードに配置する方法について説明します。

早朝、10杯目のコーヒー、小さな行で単純な正規表現を計算しているときに、クライアント(またはさらに悪いことにサーバー)のJavaアプリケーションが致命的にハングしている理由を理解しようとして失敗しました...同様の状況がすでにあなたの人生で発生している場合、あなたはおそらく、正規表現以外のバックトラックとダークについてすでに知っているでしょう残り-カットの下で歓迎します!





バックトラック、または結果の永遠の期待

(, , ), . – "evil regexes" ( ):





@Test
public void testRegexJDK8Only() {
  final Pattern pattern = Pattern.compile("(0*)*1");
  Assert.assertFalse(pattern.matcher("0000000000000000000000000000000000000000").matches());
}
      
      



: * (" ") . , ?, +, {n} (n – ).





JDK8 ( – ), JVM matches(). , .





? Pattern/Matcher java.util.regex



:





  1. * - , . , (0) , , , . .





  2. (backtrack) . ; . (0) , , . .





  3.   (0) . (0)! , , .





, "" (0), . ; – – , .





" ! ?" - . : , . , - , , 10 , . , :





@Test
public void testRegexAnyJDK() {
	final Pattern pattern = Pattern.compile("([A-Za-z,.!?]+( |\\-|\\')?){1,10}");
  Assert.assertFalse(pattern.matcher("scUojcUOWpBImlSBLxoCTfWxGPvaNhczGpvxsiqagxdHPNTTeqkoOeL3FlxKROMrMzJDf7rvgvSc72kQ").matches());
}
      
      



80 . JVM JDK8+ – 30 – , . - ReDoS-. , , , – "+" "{1,10}" – .





Java SDK?

, . , , . , . : JDK-5026912, JDK-7006761, JDK-8139263. StackOverflowError, (JDK-5050507). : " ", " ", " ". 





"" , . (, - ), API java.util.regex



JDK ( JDK-8234713, JDK-8054028, JDK-7178072). ; , " , , " (). 





. , JDK9 : , , , , . , , (JDK-6328855, ). testRegexJDK8Only()



jdk9-b119, JDK. , .





:

, , , ; , "" . , , npmjs.com. , , , , , . – , .





, , . , , . RE2, DFA - . ; – RE2 Rust, Google. JDK7+ RE2/J, C++ - .





2021 JEP-, , RE2.





RE2/J - ?

, RE2/J – . ?





  • RE2/J API Matcher;





  • ( RE2/J , – , backreferences). , ;





  • , Google, , – .





  • : " RE2/J . , , java.util.regex ".





, , : RE2/J – ; . , .





  1. ReDoS.





  2. , , , .





  3. , .





, , – , , RE2/J.








All Articles