Java
Describes how recheck checks a regular expression of the java dialect.
Engine
recheck follows the syntax and the semantics of Java 27's java.util.regex.Pattern.
Settings
The java dialect has no settings.
- CLI
- JavaScript
- Scala
$ recheck --dialect=java '/^(a|a)*$/'
import { check } from "recheck";
await check("^(a|a)*$", "", { dialect: "java" });
import codes.quine.labs.recheck.ReDoS
import codes.quine.labs.recheck.common.Parameters
import codes.quine.labs.resyntax.dialect.Dialect
ReDoS.check("^(a|a)*$", "", Parameters(dialect = Dialect.Java))
Flags and Units
The matching unit is utf16-code-point (see Matching Units).
recheck supports the following flags of java.util.regex, written as the letters of their inline flags.
| Flag | Pattern flag | Inline | Notes |
|---|---|---|---|
c | CANON_EQ | (?c) | Not supported (see Syntax Limitations). |
d | UNIX_LINES | (?d) | Only \n is a line terminator for ., ^ and $. |
i | CASE_INSENSITIVE | (?i) | Only between ASCII characters, unless with u or U. |
m | MULTILINE | (?m) | |
s | DOTALL | (?s) | |
u | UNICODE_CASE | (?u) | |
x | COMMENTS | (?x) | |
U | UNICODE_CHARACTER_CLASS | (?U) | It implies UNICODE_CASE. |
Syntax Limitations
The following constructs are not supported, and they are reported as unsupported.
- The canonical equivalence (
(?c)). \N{name}(e.g.\N{EM DASH}).- The grapheme cluster boundary (
\b{g}).
The Pattern flag LITERAL has no flag letter, so it cannot be given (Pattern.quote makes a pattern matching the same strings).
Approximations
- Java has optimizations of loops that
recheckdoes not model, so an attack thatrecheckreports may not work on Java, and the runtime-attack verification checks whether it does. \Gmatches only at the start of the input, sincerecheckmodels a search from there, not one from a later position (e.g. the second call ofMatcher#find).- Java compiles a repetition into a node that depends on its body (
Curly,GroupCurlyorLoop), and the nodes differ in captures,\Rand empty iterations.recheckdoes not reproduce the differences, and it repeats any node asLoopdoes. For example,^(?:(.)b)*cb\1$does not match"abcba"in Java, sinceGroupCurlydoes not restore the capture on backtracking, and^\R*\n$does not match"\r\n", sinceCurlydoes not backtrack into\R. - Java tries the starts of a look-behind from the shortest by the lengths that its
TreeInfocomputes, where\Xadds nothing to the maximum and the lengths can overflow asint.recheckdoes not reproduce them, and it tries the starts from the longest by the lengths of the body, as for PCRE. For example,(?<=\X)anever matches in Java, and(?<=(a|aa))bcaptures"a"of"aab"in Java, but"aa"inrecheck. - With
x, Java skips whitespace and comments also inside constructs (e.g.(?<n a>x),a{1 ,2}and\x4 1), andrecheckskips them at the same places.recheckdoes not reproduce three quirks there: Java drops the&of[a& b], reads\uD83D\ uDE00as one surrogate pair, and rejects[a- [b]], whilerecheckreads them as[a&b],\uD83Dfollowed by\anduDE00, and[a\-b].
Runtime-Attack Verification
- Command:
java --source 17 <file>.java. - Matching:
Matcher#find. - Engine limits: none.
- Engine errors:
StackOverflowError,OutOfMemoryError. - Environment variable:
RECHECK_JAVA.
java runs the program as a single-file source-code program, which needs a JDK 17 or later.