{"record":{"id":"9ff2f7a9f5827ece","repo":"jhy/jsoup","slug":"pattern-complexity-error","errorCode":null,"errorMessage":"Pattern complexity error","messagePattern":"Pattern complexity error","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/jsoup/helper/Re2jRegex.java","lineNumber":23,"sourceCode":" */\nfinal class Re2jRegex extends Regex {\n    private static final java.util.regex.Pattern unused = java.util.regex.Pattern.compile(\"\");\n    private static final String PatternComplexityError = \"Pattern complexity error\";\n\n    private final com.google.re2j.Pattern re2jPattern;\n\n    private Re2jRegex(com.google.re2j.Pattern re2jPattern) {\n        super(unused);\n        this.re2jPattern = re2jPattern;\n    }\n\n    public static Regex compile(String regex) {\n        try {\n            return new Re2jRegex(com.google.re2j.Pattern.compile(regex));\n        } catch (RuntimeException e) {\n            throw new ValidationException(\"Pattern syntax error: \" + e.getMessage());\n        } catch (OutOfMemoryError | StackOverflowError e) { // complex patterns may exhaust VM resources\n            throw new ValidationException(PatternComplexityError);\n        }\n    }\n\n    @Override\n    public Matcher matcher(CharSequence input) {\n        return new Re2jMatcher(re2jPattern.matcher(input));\n    }\n\n    @Override\n    public String toString() {\n        return re2jPattern.toString();\n    }\n\n    private static final class Re2jMatcher implements Matcher {\n        private final com.google.re2j.Matcher delegate;\n\n        Re2jMatcher(com.google.re2j.Matcher delegate) {\n            this.delegate = delegate;","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/jhy/jsoup/blob/9851ac5d9c576c6888910b5a51a2362bbc978959/src/main/java/org/jsoup/helper/Re2jRegex.java#L5-L41","documentation":"When compiling a pattern causes OutOfMemoryError or StackOverflowError (RE2 compiles may exhaust VM resources on huge bounded repetitions like (x){0,1000000} or deeply nested groups), compile throws ValidationException with the constant PatternComplexityError. It distinguishes resource exhaustion from plain syntax errors.","triggerScenarios":"Compiling regexes with extremely large counted repetitions (e.g. a{0,100000}), very deep nesting, or enormous alternation sets that blow up RE2's compile-time automaton construction.","commonSituations":"User-supplied regex limits that compile into huge NFAs; generated patterns embedding big counts; security-sensitive endpoints accepting arbitrary regexes (ReDoS-hardening paths) where input size is unchecked.","solutions":["Reduce repetition bounds and nesting in the pattern; simplify or split it","Cap user-supplied pattern length and repetition counts before compiling","Catch ValidationException and reject overly complex patterns with a friendlier message","Pre-validate structure (e.g. limit max {m,n} values) with a lint pass"],"exampleFix":"// before\nRegex r = Re2jRegex.compile(\"(a|b|c){0,200000}\");\n// after\nRegex r = Re2jRegex.compile(\"(a|b|c){0,100}\"); // bounded complexity","handlingStrategy":"validation","validationCode":"if (pattern.length() > 500 || java.util.regex.Pattern.compile(\"\\\\\\\\{\\\\s*\\\\d{4,}\").matcher(pattern).find()) throw new IllegalArgumentException(\"Pattern too complex\");","typeGuard":"boolean isBoundedPattern(String p) { return p.length() <= 500 && !p.matches(\".*\\\\{\\\\d{4,}.*\"); }","tryCatchPattern":"try { Regex r = Re2jRegex.compile(pattern); } catch (ValidationException e) { if (e.getMessage().contains(\"complexity\")) { /* reject as too complex */ } }","preventionTips":["Cap pattern length and {m,n} repetition bounds for user input","Simplify or split huge alternations and nested groups","Monitor for OOM/StackOverflow during regex compilation in tests"],"tags":["regex","validation","re2","resource-exhaustion"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"9851ac5d9c576c6888910b5a51a2362bbc978959","analyzedAt":"2026-09-08T15:22:04.931Z","contentChangedAt":"2026-09-08T15:22:04.931Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}