fix: add unicode flag to regex to prevent accented character false positives - #43
Conversation
…sitives (#24) Multi-byte UTF-8 characters (ê, é) were matched byte-by-byte without the /u flag, causing false profanity detections for words like "tête" and "aré". Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughUpdates profanity detection to be Unicode-aware and normalizes input encoding: the profanity regex now uses the 'u' flag for Unicode matching; input strings are coerced to UTF-8 when needed; tests added/updated to cover accented French words and regex expectation. Changes
Sequence Diagram(s)(Skipped — changes are small and do not introduce a new multi-component control flow requiring a sequence diagram.) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/Generators/ProfanityExpressionGenerator.php`:
- Around line 155-157: The generated regex in ProfanityExpressionGenerator (uses
self::SEPARATOR_PLACEHOLDER and builds $expression with '/.../iu') can fail
silently on invalid UTF-8 when used by BlaspService::check(); ensure the input
is validated/normalized to UTF-8 before any normalization/regex work (use
mb_check_encoding() and, if invalid, convert with mb_convert_encoding(...,
'UTF-8', 'auto') or reject and log), and also add post-regex error handling in
the caller (after preg_match_all in BlaspService::check()) by checking
preg_last_error() and logging or falling back to a safe behavior; update
relevant places where the string enters processing so invalid-UTF8 cases are
handled before ProfanityExpressionGenerator is used.
Ensures invalid UTF-8 strings are sanitized before reaching preg_match with the /u flag, preventing silent regex failures. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/BlaspService.php (1)
366-400: Byte-based string operations are unsafe with potentially multi-byte-containing strings.The method uses byte-based operations (
strlen(), array index access$string[$i],substr()) which do not handle multi-byte UTF-8 characters correctly. While the normalizers for French, German, and Spanish convert accented characters to ASCII equivalents, the English normalizer returns the input unchanged, and other normalizers may not cover all characters. If$normalizedStringcontains any multi-byte UTF-8 characters, byte-level array access like$string[$tokenStart - 1]can land on the middle of a multi-byte sequence, causingpreg_match()to behave unexpectedly.Additionally, lines 341–342 elsewhere in the file already use
mb_strlen()andmb_substr()for UTF-8 safety, showing the codebase is UTF-8-aware. This method should use the same approach:mb_strlen(),mb_substr(), and eithermb_str_split()orpreg_match()with the/uflag for safe character iteration.
🧹 Nitpick comments (1)
src/BlaspService.php (1)
260-262: Encoding conversion assumes malformed UTF-8, not alternative encodings.The current approach correctly sanitizes invalid UTF-8 byte sequences, but if the input is in a different encoding entirely (e.g., ISO-8859-1, Windows-1252), specifying
'UTF-8'as the source encoding will corrupt the data rather than convert it properly.Consider detecting the actual encoding for more robust handling:
♻️ Suggested improvement
- if (!mb_check_encoding($string, 'UTF-8')) { - $string = mb_convert_encoding($string, 'UTF-8', 'UTF-8'); - } + if (!mb_check_encoding($string, 'UTF-8')) { + $detected = mb_detect_encoding($string, ['UTF-8', 'ISO-8859-1', 'Windows-1252', 'ASCII'], true); + $string = mb_convert_encoding($string, 'UTF-8', $detected ?: 'ISO-8859-1'); + }Alternatively, if you intentionally want to strip invalid sequences rather than convert from other encodings, document this behavior with a comment explaining that non-UTF-8 encoded input may lose data.
Summary
/u(PCRE_UTF8) flag to generated profanity regex patterns, fixing false positives caused by multi-byte UTF-8 characters (e.g.ê,é) being matched byte-by-byteTest plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.