Regex Control Escape Out Of Range

ID

java.regex_control_escape_out_of_range

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

code-style

Description

Reports a \cX control escape inside a regex literal whose character X is not one of @, an uppercase ASCII letter, [, \, ], ^ or _.

Rationale

Java computes the control character for \cX by XORing the character code of X with 0x40, unconditionally and without validating the result. That formula only lands on a sensible control character when X is in the ASCII block 0x40-0x5F — spelled out, @, A-Z, [, \, ], ^ or _.

Feed it anything else and the escape does not fail: it silently produces some other character, one the author never intended:

Pattern.compile("\\ca");  // XORs 'a' (0x61) with 0x40 -> 0x21, not the control char meant
Pattern.compile("\\c!");  // '!' (0x21) is nowhere near the intended range either

Case matters here, unlike in some other regex engines: \ca and \cA compute two different characters, so a lower-case letter is reported too, not folded to its upper-case form.

Remediation

Use an upper-case letter (or one of @ [ \ ] ^ _) matching the exact control character intended, or spell the character out with a \u escape instead of relying on the XOR trick:

Pattern.compile("\\cA");   // start of heading, spelled correctly
Pattern.compile("\\u0001"); // equivalent, and unambiguous about the intended value

What is not reported

A \c with nothing following it — for example at the very end of the pattern — is a malformed escape, not this rule’s concern; the resulting PatternSyntaxException is reported elsewhere.

© 2026 Xygeni. All rights reserved