oracle/graal · error · UnsupportedRegexException
Literal parsing is not supported
Error message
Literal parsing is not supported
What it means
JavaRegexLexer rejects Pattern.LITERAL at construction with UnsupportedRegexException: literal (non-meta) parsing mode is not implemented by the TRegex Java-flavor frontend, even though java.util.regex supports treating the whole pattern as a literal string.
Source
Thrown at regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/flavor/java/JavaRegexLexer.java:155
}
}
private static final TBitSet WHITESPACE = TBitSet.valueOf('\t', '\n', '\f', '\r', ' ');
private static final TBitSet PREDEFINED_CHAR_CLASSES = TBitSet.valueOf('D', 'H', 'S', 'V', 'W', 'd', 'h', 's', 'v', 'w');
private static final TBitSet LATIN1_CHARS_THAT_CASE_FOLD_TO_NON_LATIN1_CHARS = TBitSet.valueOf(0x49, 0x4b, 0x53, 0x69, 0x6b, 0x73, 0xb5, 0xc5, 0xe5, 0xff);
final JavaUnicodeProperties unicode;
private final Deque<JavaFlags> flagsStack = new ArrayDeque<>();
private JavaFlags currentFlags;
private final CodePointSetAccumulator curCharClass = new CodePointSetAccumulator();
public JavaRegexLexer(RegexSource source, JavaFlags flags, CompilationBuffer compilationBuffer) {
super(source, compilationBuffer);
if (flags.isCanonEq()) {
throw new UnsupportedRegexException("Canonical equivalence is not supported");
}
if (flags.isLiteral()) {
throw new UnsupportedRegexException("Literal parsing is not supported");
}
this.unicode = JavaUnicodeProperties.create(source.getOptions());
this.currentFlags = flags;
}
@Override
protected boolean isPredefCharClass(char c) {
return PREDEFINED_CHAR_CLASSES.get(c);
}
JavaFlags getLocalFlags() {
return currentFlags;
}
public void pushLocalFlags() {
flagsStack.push(currentFlags);
}
View on GitHub (pinned to a66e9ccd1d)
Solutions
- Quote the pattern manually instead of using the flag: Pattern.compile(Pattern.quote(userInput)) without LITERAL.
- For simple substring search, skip regex entirely and use String.contains/String.indexOf or TruffleString operations.
- Update libraries that unconditionally pass LITERAL, or run them on a context where the host engine handles the compile.
Example fix
// before Pattern p = Pattern.compile(userInput, Pattern.LITERAL); // throws on TRegex // after Pattern p = Pattern.compile(Pattern.quote(userInput)); // equivalent literal semantics
Defensive patterns
Strategy: fallback
Validate before calling
if ((flags & Pattern.LITERAL) != 0) {
pattern = Pattern.quote(pattern);
flags &= ~Pattern.LITERAL;
} Try / catch
try {
return Pattern.compile(pattern, flags);
} catch (com.oracle.truffle.regex.UnsupportedRegexException e) {
if ((flags & Pattern.LITERAL) != 0) {
return Pattern.compile(Pattern.quote(pattern), flags & ~Pattern.LITERAL);
}
throw e;
} Prevention
- Use Pattern.quote(...) instead of the LITERAL flag — portable across engines.
- For plain substring search, prefer indexOf/contains over regex entirely.
- Upgrade or patch libraries that hard-code Pattern.LITERAL.
When it happens
Trigger: Pattern.compile(userInput, Pattern.LITERAL) executed on Espresso/TRegex, or any library that uses LITERAL to safely match arbitrary user-provided strings containing regex metacharacters.
Common situations: Search/replace features that take raw user text as a pattern; security-conscious code that deliberately avoids pattern injection by using LITERAL; log-grepping tools running on GraalVM.
Related errors
- Canonical equivalence is not supported
- Syntax '{}' not recognized
- Path component is undefined
- Path component should be '/'
- Query component present
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/d2b2a14817224256.
Report an issue: GitHub.