[php-src] Issue #23094: ext/intl: NumberFormatter::parse() and parseCurrency() use UTF-16 offsets for UTF-8 strings
[email protected] (LamentXU123)
| Newsgroups | php.bugs |
|---|---|
| Message-ID | <jLdSEbDQQRRkL0jPrJDH2PocqEi8c2fzjOU4SAJEDP8@main.internal.php.net> |
Issue: https://github.com/php/php-src/issues/23094
Author: LamentXU123
### Description
This happens in my own app:
```php
<?php
$formatter = new NumberFormatter('en_US', NumberFormatter::DECIMAL);
$prefix = "\u{1F600}"; // 😀
$input = $prefix . '123';
$offset = strlen($prefix);
var_dump(strlen($input));
var_dump($offset);
var_dump($formatter->parse(
$input,
NumberFormatter::TYPE_INT32,
$offset
));
var_dump($offset);
```
```
int(7)
int(4)
int(3)
int(5)
```
While I expect
```
int(7)
int(4)
int(123)
int(7)
```
The emoji occupies 4 bytes in the PHP UTF-8 string but 2 UTF-16 code units in ICU. Very sure this is the reason.
The input offset should be converted from a UTF-8 byte offset to a UTF-16 code-unit offset before calling ICU. Ehhhhhhh unfortunately I think this happens commonly throughout the code base. So I might be planning some bigger refactor to solve this. Buggy stuff.
Since this is a rather easy case to solve, I will open this as an issue here. If anyone want to start a contribution to the intl extension. They can try to solve this as a good head start. This should be easier than JIT bugs anyways. Feel free to open a PR :)
### PHP Version
```plain
All supported version.
```
### Operating System
N/A