Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8349347

Very long-running regex with Matcher.find

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 8
    • core-libs
    • None

      From external source, Tim Allison:

      I haven't seen any blog posts about this particular issue, and it seems like the regex engine should do something smarter. This is not the well known backtracking reDos thing or the well known stackoverflow kind of thing.
      The trigger is a numeric quantifier operator attached to basically nothing.
      I may be using the wrong terms.
      an example {04184633}278-]4^6665]7
      This comes from fuzzing...

      Our reproducer:
      jshell> time(() -> Pattern.compile("{1}3234512234").matcher("123".repeat(100)).find())
      0s

      jshell> time(() -> Pattern.compile("{12}3234512234").matcher("123".repeat(100)).find())
      0s

      jshell> time(() -> Pattern.compile("{123}3234512234").matcher("123".repeat(100)).find())
      0s

      jshell> time(() -> Pattern.compile("{1234}3234512234").matcher("123".repeat(100)).find())
      0s

      jshell> time(() -> Pattern.compile("{12345}3234512234").matcher("123".repeat(100)).find())
      0.0009993s

      jshell> time(() -> Pattern.compile("{123456}3234512234").matcher("123".repeat(100)).find())
      0.0040019s

      jshell> time(() -> Pattern.compile("{1234567}3234512234").matcher("123".repeat(100)).find())
      0.0320831s

      jshell> time(() -> Pattern.compile("{12345678}3234512234").matcher("123".repeat(100)).find())
      0.3749385s

      jshell> time(() -> Pattern.compile("{123456789}3234512234").matcher("123".repeat(100)).find())
      3.9860775s

      jshell> time(() -> Pattern.compile("{1234567890}3234512234").matcher("123".repeat(100)).find())
      38.638369s

      With time() defined as:
             void time(Runnable runnable) {
                 var start = java.time.Instant.now();
                 runnable.run();
                 var duration = java.time.Duration.between(start, java.time.Instant.now());
                 System.out.println(duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase());
             }

            igraves Ian Graves
            cstein Christian Stein
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: