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