Repository navigation
[Mbstring] Update the East Asian Width ranges of mb_strwidth() - #722
Conversation
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
|
Would Unicode 18 give the same map? |
|
Almost: Unicode 18.0.0 only adds to it. Its EastAsianWidth.txt has 990 more W/F code points than 17.0.0 and none fewer, and all 990 are characters first assigned in 18.0 (e.g. U+18CD6..U+18CDA, U+18E00..U+19191, U+191A0..U+191D2, U+1B123..U+1B128, U+1F6D9, U+1FA8B..U+1FA8D). Every code point that is W or F in 17.0.0 is still W or F in 18.0.0. I used 17.0.0 because that is what PHP 8.5's mbstring uses: with it, an all code point scan of |
|
Thank you @wleeaf. |
mb_strwidth()counts a character as two columns when it matches a hard-coded list of ranges. That list predates the emoji and most of the additions to EastAsianWidth.txt, so the polyfill and ext/mbstring disagree on many characters:This mostly shows up as misaligned columns in CLI tables and progress output that contain emoji, when mbstring is not installed.
ext/mbstring treats the
WandFcode points of EastAsianWidth.txt as wide. A newCompiler::eastAsianWidthRegexp()builds the same set from that file, andupdate-unidata.phpdownloads the file and writesResources/unidata/eastAsianWidthRegexp.php.mb_strwidth()loads the regexp likemb_convert_case()loadstitleCaseRegexp. The committed file comes from Unicode 17.0.0. With it, a scan of every code point gives the same width as PHP 8.5'smb_strwidth()(0 differences, against 115 differing ranges before).The new assertion in
testStrwidth()calls the polyfill directly. It fails without the change and passes with it../phpunit tests/Mbstringpasses, including the ill-formed UTF-8 cases.