Missing Characters
I release a new version of Xdebug on Sunday, which fixes a few bugs. One of them is titled emoji character become diamond question marks. This bug turned out to be the same as var_dump does not output some Cyrillic characters, which was originally reported a few days earlier but hadn't come with a decent enough reproducible case.
At first I dismissed this, as it's not unlikely that people get their character sets wrong, or mixed up.
But when I tested it, the following script really did not show the right result:
<?php $str = 'hello 👍'; var_dump($str); ?>
Instead of the expected:
<pre class='xdebug-var-dump' dir='ltr'> <small>Standard input code:3:</small><small>string</small> <font color='#cc0000'>'hello 👍'</font> <i>(length=10)</i> </pre>
It showed:
<pre class='xdebug-var-dump' dir='ltr'> <small>Standard input code:3:</small><small>string</small> <font color='#cc0000'>'hello ���'</font> <i>(length=10)</i> </pre>
The four bytes that should have made up the 👍 had turned into three.
Xdebug uses a function, xdebug_xmlize, to escape XML and XHTML-special characters such as ", &, and < when it outputs strings of data.
Its algorithm first calculates how much memory the resulting string would use by looping over the source characters, and adding the lengths of the escaped characters together. It uses a 256-entry table for this.
The first row shows that byte 0's escaped length will be 4 (for �) and the LF character's escaped length will be 5 (for ).
The replacement strings are recorded in the table that follows. It only has place for 64 elements, as none of the bytes above byte-64 need to be escaped. You can see that because the xml_encode_count table only has entries containing 1 after the fourth 16-element row.
Then in a second iteration it loops over all the source characters again to construct the resulting output.
In this iteration, it checks if the destination length is 1, in which case it just copies the character over. If the destination length is not 1, then it adds the number of characters that correspond to the destination character's length.
The bug here was that the table for xml_encode_count, although it was defined as having 256 entries, only had 240 entries. I had missed to add the 16th line, so instead there were only 15 lines of 16 elements.
And in C, that means that these missing elements were all set to 0. This meant that if there was a character in the source string where the byte value was larger or equal to hexadecimal 0xF0 (decimal: 240), the algorithm thought the replacement length of these characters would be 0. This then resulted in these characters to just be ignored, and not copied over into the destination string.
For the 👍 character (hex: 0xF0 0x9F 0x91 0x8D) that meant that its first byte (0xF0) was not copied into the destination string. And that meant a broken UTF-8 character. Oops! 💩
In Xdebug 3.4.2 this is now fixed, as I have added the 16th line to the table, with 16 more elements containing 1.
What I did find curious that it took nearly five years for something to report this issue, and with that, two in the same week!
Likes
Life Line
Updated an estate_agent office
My First Lapwing!
I went to the London Wetland Centre yesterday, for a day out in nature.
While hiding in a hide, this chap and a friend showed up starting to forage for grubs.
#BirdPhotography #BirdsOfMastodon #Photography #Birds #London #Nature
Created a waste_basket; Updated a cafe and a restaurant; Confirmed an estate_agent office
@bennuttall Are you at the Crucible this year again?
I walked 9.7km in 5h29m12s
Updated a gate
Staring Contest with a Squirrel
On my walk on the weekend, I sat down on a tree branch of a tree that had fallen over some time ago. Just listening to the birds.
Then after hearing rustling in the foliage above me, I looked up, and saw this chap staring at me.
I walked 3.0km in 41m38s
I walked 1.1km in 12m20s
Bluebell Carpet
I had a lovely walk on Hampstead Heath yesterday, finding all the nooks and crannies away from the busy paths.
This field of bluebells under the colourful tree was a stand-out quiet spot.
I walked 2.3km in 21m51s
Fix paths
Created a memorial
Created a bench
@Edent Seems like my Android stopped sending coordinates to @openbenches as well, which is surprising as I haven't updated anything as far as I'm aware. Could it be a problem with the reader in your side after the latest changes and the addition of the warning?
I walked 5.8km in 2h15m45s
I walked 1.7km in 17m46s
I walked 4.8km in 1h39m40s
Add the new Queen Elizabeth II garden.
Updated a bench and a crossing; Deleted 2 kerbs
Created 3 gates and a waste_basket
Created 6 benches
Created a bench; Updated 4 benches
Created 2 benches and a bicycle_parking; Updated a telephone and a waste_basket
I walked 10.3km in 2h34m24s




Shortlink
This article has a short URL available: https://drck.me/missing-chars-jdk