Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 34 additions & 34 deletions docs/bootstrap-inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -13975,40 +13975,40 @@ Rank live CFG gaps across inventory files: `php script/bootstrap-inventory-triag
- new NumberFormatterGetErrorMessage (line 265)
- new Error (line 283)
- new ObjectEntry (line 285)
- new ArgumentCountError (line 1857)
- new Error (line 1865)
- new ArgumentCountError (line 1889)
- new ArgumentCountError (line 1919)
- new Error (line 1927)
- new ArgumentCountError (line 1959)
- new Error (line 1967)
- new ArgumentCountError (line 1996)
- new Error (line 2004)
- new ArgumentCountError (line 2059)
- new Error (line 2067)
- new ArgumentCountError (line 2120)
- new Error (line 2128)
- new ArgumentCountError (line 2160)
- new Error (line 2168)
- new ArgumentCountError (line 2192)
- new Error (line 2200)
- new ArgumentCountError (line 2228)
- new Error (line 2236)
- new ArgumentCountError (line 2260)
- new Error (line 2268)
- new ArgumentCountError (line 2296)
- new Error (line 2304)
- new ArgumentCountError (line 2328)
- new Error (line 2336)
- new ArgumentCountError (line 2363)
- new Error (line 2371)
- new ArgumentCountError (line 2394)
- new Error (line 2402)
- new ArgumentCountError (line 2429)
- new Error (line 2437)
- new ArgumentCountError (line 2458)
- new Error (line 2466)
- 71 class method(s)
- new ArgumentCountError (line 1868)
- new Error (line 1876)
- new ArgumentCountError (line 1900)
- new ArgumentCountError (line 1930)
- new Error (line 1938)
- new ArgumentCountError (line 1970)
- new Error (line 1978)
- new ArgumentCountError (line 2007)
- new Error (line 2015)
- new ArgumentCountError (line 2070)
- new Error (line 2078)
- new ArgumentCountError (line 2131)
- new Error (line 2139)
- new ArgumentCountError (line 2171)
- new Error (line 2179)
- new ArgumentCountError (line 2203)
- new Error (line 2211)
- new ArgumentCountError (line 2239)
- new Error (line 2247)
- new ArgumentCountError (line 2271)
- new Error (line 2279)
- new ArgumentCountError (line 2307)
- new Error (line 2315)
- new ArgumentCountError (line 2339)
- new Error (line 2347)
- new ArgumentCountError (line 2374)
- new Error (line 2382)
- new ArgumentCountError (line 2405)
- new Error (line 2413)
- new ArgumentCountError (line 2440)
- new Error (line 2448)
- new ArgumentCountError (line 2469)
- new Error (line 2477)
- 72 class method(s)

### `ext/intl/VmResourceBundle.php`

Expand Down
27 changes: 19 additions & 8 deletions ext/intl/VmNumberFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -531,14 +531,14 @@ public static function parse(
$start = 0;
}
if ($start > \strlen($value)) {
self::fail($formatter, 'numfmt_parse: Number parsing failed: U_PARSE_ERROR');
self::failParse($formatter);

return false;
}
$slice = \substr($value, $start);
$prefix = self::matchNumberPrefix($slice, $state['locale']);
if (null === $prefix) {
self::fail($formatter, 'numfmt_parse: Number parsing failed: U_PARSE_ERROR');
self::failParse($formatter);

return false;
}
Expand All @@ -551,7 +551,7 @@ public static function parse(
// Fallback: historic full-string sanitize for whitespace / odd separators.
$num = self::parseNumberString($value, $state['locale']);
if (null === $num) {
self::fail($formatter, 'numfmt_parse: Number parsing failed: U_PARSE_ERROR');
self::failParse($formatter);

return false;
}
Expand Down Expand Up @@ -599,7 +599,7 @@ public static function parseCurrency(
$start = 0;
}
if ($start > \strlen($value)) {
self::fail($formatter, 'numfmt_parse_currency: Currency parsing failed: U_PARSE_ERROR');
self::failParse($formatter);
$currencyOut = null;

return false;
Expand All @@ -608,7 +608,7 @@ public static function parseCurrency(
$slice = $hasOffset ? \substr($value, $start) : $value;
$parsed = self::parseCurrencySlice($slice, $state['locale']);
if (null === $parsed) {
self::fail($formatter, 'numfmt_parse_currency: Currency parsing failed: U_PARSE_ERROR');
self::failParse($formatter);
$currencyOut = null;

return false;
Expand Down Expand Up @@ -1036,11 +1036,22 @@ public static function coerceStringArg(Variable $var, string $function, int $pos
return VmString::coerceStringBuiltinArg($var, $function, $position, $name);
}

private static function fail(ObjectEntry $formatter, string $message): void
private static function fail(ObjectEntry $formatter, string $message, int $code = IntlError::U_ILLEGAL_ARGUMENT_ERROR): void
{
IntlError::set(IntlError::U_ILLEGAL_ARGUMENT_ERROR, $message);
IntlError::set($code, $message);
if (isset(self::$state[$formatter->id])) {
self::$state[$formatter->id]['errorCode'] = IntlError::U_ILLEGAL_ARGUMENT_ERROR;
self::$state[$formatter->id]['errorCode'] = $code;
self::$state[$formatter->id]['errorMessage'] = $message;
}
}

/**
* Parse/parseCurrency failure — object error only (php-src leaves intl_get_error_code at 0) (#22855).
*/
private static function failParse(ObjectEntry $formatter, string $message = 'Number parsing failed: U_PARSE_ERROR'): void
{
if (isset(self::$state[$formatter->id])) {
self::$state[$formatter->id]['errorCode'] = IntlError::U_PARSE_ERROR;
self::$state[$formatter->id]['errorMessage'] = $message;
}
}
Expand Down
26 changes: 26 additions & 0 deletions test/compliance/cases/intl/numberformatter_parse_error_code.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
NumberFormatter::parse error is U_PARSE_ERROR (9); global intl error stays 0 (#22855)
--SKIPIF--
<?php
if (!\PHPCompiler\ext\intl\IntlExtensionPolicy::runsIntlOopCompliance(basename(__FILE__))) {
echo 'skip NumberFormatter withheld until extension_loaded(\'intl\') (#19670)';
}
?>
--FILE--
<?php
$f = new NumberFormatter('en_US', NumberFormatter::DECIMAL);
$r = $f->parse('not-a-number');
echo 'r=', var_export($r, true), "\n";
echo 'code=', $f->getErrorCode(), "\n";
echo 'msg=', $f->getErrorMessage(), "\n";
echo 'gcode=', intl_get_error_code(), "\n";
echo 'ok=', $f->parse('1,234.5'), "\n";
echo 'ok_code=', $f->getErrorCode(), "\n";
?>
--EXPECT--
r=false
code=9
msg=Number parsing failed: U_PARSE_ERROR
gcode=0
ok=1234.5
ok_code=0
11 changes: 11 additions & 0 deletions test/repro/issue_22855_numfmt_parse_error.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Repro #22855 — NumberFormatter::parse failure → U_PARSE_ERROR (9), global intl error stays 0.
*/
$f = new NumberFormatter('en_US', NumberFormatter::DECIMAL);
$r = $f->parse('not-a-number');
var_export($r);
echo "\n";
echo $f->getErrorCode(), "\n";
echo $f->getErrorMessage(), "\n";
echo intl_get_error_code(), "\n";
Loading