{"record":{"id":"17d3b405efde8299","repo":"oracle/graal","slug":"character-class-maximum-nesting-level-exceeded","errorCode":null,"errorMessage":"Character class maximum nesting level exceeded","messagePattern":"Character class maximum nesting level exceeded","errorType":"exception","errorClass":"UnsupportedRegexException","httpStatus":null,"severity":"error","filePath":"regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/flavor/java/JavaRegexLexer.java","lineNumber":613,"sourceCode":"                }\n            }\n            if (p == null) {\n                throw syntaxError(JavaErrorMessages.unknownUnicodeCharacterProperty(name), ErrorCode.InvalidCharacterClass);\n            }\n        }\n        if (invert) {\n            // TODO reference implementation has something with hasSupplementary, do we care about\n            // this?;\n            p = p.createInverse(Encoding.UTF_16);\n        }\n        return ClassSetContents.createCharacterClass(p);\n    }\n\n    private CodePointSet parseCharClassInternal(boolean consume) throws RegexSyntaxException {\n        charClassNesting++;\n        try {\n            if (charClassNesting > TRegexOptions.TRegexParserTreeMaxNestingLevel) {\n                throw new UnsupportedRegexException(\"Character class maximum nesting level exceeded\");\n            }\n            return parseCharClassInternalBody(consume);\n        } finally {\n            charClassNesting--;\n        }\n    }\n\n    private CodePointSet parseCharClassInternalBody(boolean consume) throws RegexSyntaxException {\n        boolean invert = false;\n        // negation can only occur after a bracket, we cannot have negation after '&&' for example\n        if (curChar() == '^' && pattern.charAt(position - 1) == '[') {\n            advance();\n            invert = true;\n        }\n\n        CodePointSet curr = null;\n        CodePointSet prev = null;\n","sourceCodeStart":595,"sourceCodeEnd":631,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/flavor/java/JavaRegexLexer.java#L595-L631","documentation":"JavaRegexLexer.parseCharClassInternal counts nesting of '[' inside character classes and rejects patterns whose nesting exceeds the TRegexOptions.TRegexParserTreeMaxNestingLevel option, throwing UnsupportedRegexException to bound parser recursion (and avoid stack overflow) on deeply nested classes.","triggerScenarios":"Compiling a Java-flavor pattern with nested character classes or class-set operations deeper than the configured limit, e.g. repeated '[a[b[c[...]]]]' or machine-generated patterns with many nested intersections '[[[...]]]'.","commonSituations":"Programmatic pattern builders (e.g. alternation-to-class optimizations) that nest classes recursively; fuzzed input fed to a regex compiler; generated word-matching patterns from large dictionaries.","solutions":["Flatten the pattern: merge nested classes into one set ([abc] instead of [a[b[c]]]) or hoist common parts.","Raise the engine option regex.TRegexParserTreeMaxNestingLevel if deeper nesting is legitimate for your workload.","Cap pattern complexity at the generator so emitted nesting stays under the configured limit."],"exampleFix":"// before\nString p = \"[[[[[[[a-z]]]]]]]\"; // nesting > limit -> throws\n\n// after\nString p = \"[a-z]\"; // flattened equivalent\n// or, when deep nesting is required:\n// Context option: regex.TRegexParserTreeMaxNestingLevel=1000","handlingStrategy":"validation","validationCode":"static int maxClassNesting(String pattern) {\n    int depth = 0, max = 0;\n    boolean inClass = false;\n    for (int i = 0; i < pattern.length(); i++) {\n        char c = pattern.charAt(i);\n        if (c == '\\\\') { i++; continue; }\n        if (c == '[') { depth++; max = Math.max(max, depth); }\n        else if (c == ']') { depth = Math.max(0, depth - 1); }\n    }\n    return max;\n}\n// reject or flatten when maxClassNesting(p) > limit (default TRegexParserTreeMaxNestingLevel)","typeGuard":null,"tryCatchPattern":"try {\n    return engine.compile(pattern);\n} catch (com.oracle.truffle.regex.UnsupportedRegexException e) {\n    if (e.getMessage().contains(\"nesting level\")) {\n        return engine.compile(flattenCharacterClasses(pattern));\n    }\n    throw e;\n}","preventionTips":["Flatten nested character classes at pattern-generation time ([a[b[c]]] -> [abc]).","Cap generator output nesting below the TRegexParserTreeMaxNestingLevel option.","Raise regex.TRegexParserTreeMaxNestingLevel deliberately (with a stack-depth budget) rather than as a blind retry."],"tags":["regex","truffle","parser-limits","nesting","character-class","configuration"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}