Image Captcha generates incorrect codes when using multibyte characters such as Japanese.
* Example:
- Characters to use in the code: あかさたなは
- Code length: 5
- Generated code: あかさあかさあかさたなはあかさ
- Desirable code: はたかなさ
This issue is caused by issue #3184909, “Fix coding standard for php strlen and substr”.
https://www.drupal.org/project/captcha/issues/3184909
This issue occurs in versions 8.x-1.7 through the latest version 2.0.7.
The code is correct before the patch was applied. Using a multibyte function for single-byte processing logic is incorrect. It is working correctly in version 7.x.
Please revert back to the pre-patch version.
Issue fork captcha-3495425
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
sriram_s commentedThe image CAPTCHA becomes unreadable with any non-ASCII character set because the code characters get merged together. Root cause is in _image_captcha_utf8_split(): it advances through the string by byte offset but pulls each character with mb_substr(), which counts by character. Those two disagree the moment a multibyte character shows up, so characters get bundled into wrong-sized groups. ASCII sets are unaffected, which is presumably why it slipped through.
mula's read on this was correct. The function is basically re-implementing mb_str_split() by hand, and doing it wrong, so MR !140 just swaps in mb_str_split() and drops the manual byte-walking. Added a kernel test with ASCII / two-byte / three-byte / mixed inputs to lock it down.
Setting to needs review.
Comment #6
japerryThe issue brought up by the MR is right, and so is the fix. `mb_str_split()` (PHP 7.4+) is exactly what the helper was trying to be, and the function signature is unchanged. I rebased MR !140 onto current 2.x and added one commit that tidies the kernel test: strict types, final class, no redundant include, and a four-byte (emoji) case.
Comment #8
japerry