Regex Java - Catastrophic backtracking

Dependency Maven re2j

<dependency>
   <groupId>com.google.re2j</groupId>
   <artifactId>re2j</artifactId>
   <version>1.7</version>
</dependency>

Java Catastrophic backtracking

public class Main {

  public static void main(String[] args) throws InterruptedException {

    // Regex responsable d'un effet Catastrophic backtracking
    final String regex = "(h|h|ih(((i|a|c|c|a|i|i|j|b|a|i|b|a|a|j))+h)ahbfhba|c|i)*";

    // L'input qui va provoquer un Catastrophic backtracking
    final String input = "hchcchicihcchciiicichhcichcihcchiihichiciiiihhcchi" +
      "cchhcihchcihiihciichhccciccichcichiihcchcihhicchcciicchcccihiiihhihihihi" +
      "chicihhcciccchihhhcchichchciihiicihciihcccciciccicciiiiiiiiicihhhiiiihchccch" +
      "chhhhiiihchihcccchhhiiiiiiiicicichicihcciciihichhhhchihciiihhiccccccciciihh" +
      "ichiccchhicchicihihccichicciihcichccihhiciccccccccichhhhihihhcchchihih" +
      "iihhihihihicichihiiiihhhhihhhchhichiicihhiiiiihchccccchichci";

    // Le thread ne se terminera jamais avec java.util.regex
    Thread t2 = new Thread(() -> {
      boolean result = java.util.regex.Pattern.matches(regex, input);
      System.out.println("Le résultat pour java.util.regex est " + result);
    });
    t2.start();

    // Le thread va se terminer avec la librairie re2j. Le résultat est vrai
    Thread t = new Thread(() -> {
      boolean result = com.google.re2j.Pattern.matches(regex, input);
      System.out.println("Le résultat pour com.google.re2j est " + result);
    });
    t.start();

    // Timeout de 3 secondes
    Thread.sleep(3000);

    System.out
      .println("Le thread avec java.util.regex " + (t2.isAlive() ? "n'est pas terminé" : "est terminé"));
    System.out.println("Le thread avec com.google.re2j " + (t.isAlive() ? "n'est pas terminé" : "est terminé"));

    System.exit(0);

  }

}

Commentaires