Regex Missing Unicode Case
ID |
java.regex_missing_unicode_case |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
code-style |
Description
Reports a regex matched case-insensitively (Pattern.CASE_INSENSITIVE, or an inline (?i) / (?i:…)) whose pattern contains a non-ASCII letter, while neither UNICODE_CASE nor UNICODE_CHARACTER_CLASS is also enabled.
Rationale
CASE_INSENSITIVE on its own only folds case within the ASCII alphabet. Outside it — an umlaut, an accented Latin letter, a Cyrillic or Greek letter — case folding does not happen unless UNICODE_CASE (or the broader UNICODE_CHARACTER_CLASS, which implies it) is enabled too:
Pattern.compile("müller", Pattern.CASE_INSENSITIVE);
// matches "müller" but not "MÜLLER" - the umlaut stays case-sensitive
The pattern reads as case-insensitive, compiles without complaint, and quietly fails to match perfectly reasonable input the moment a non-ASCII letter’s case differs from the one written in the pattern.
Remediation
Add UNICODE_CASE alongside CASE_INSENSITIVE (or use UNICODE_CHARACTER_CLASS, which implies it), or use the matching inline flag combination:
Pattern.compile("müller", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
str.matches("(?iu)müller");
What is not reported
A pattern with no letters at all is never reported, whatever flags it carries — there is nothing for case-insensitivity to apply to. A non-ASCII letter written as a \u escape is treated the same as the raw character, since the two are indistinguishable once decoded. A scoped (?i:…) only makes the rule look at letters inside that group; a non-ASCII letter elsewhere in the pattern is unaffected by it and stays unreported.