[php-src] master: ext/intl: Fix stale intl error state in IntlNumberRangeFormatter (#23191)

Weilin Du via GitHub <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Weilin Du (LamentXU123)
Committer: GitHub (web-flow)
Pusher: LamentXU123
Date: 2026-08-10T15:58:31+08:00

Commit: https://github.com/php/php-src/commit/66ceedae95d9bfc3d286aa86f12ae6c92077f719
Raw diff: https://github.com/php/php-src/commit/66ceedae95d9bfc3d286aa86f12ae6c92077f719.diff

ext/intl: Fix stale intl error state in IntlNumberRangeFormatter (#23191)

IntlNumberRangeFormatter::createFromSkeleton() and
IntlNumberRangeFormatter::format() did not reset intl error state. This commit
fix it.

I know this is yet another "error state" fixes. Unfortunately we couldn't use
the function macro added before because these are methods, and we can only
reset the error state manually so far.

I personally hate the error state design. I think we should throw exceptions
instead. But considering BC breaks... this is just an idea in the void.

IntlNumberRangeFormatter is added in 8.6 so this is the correct branch.

Changed paths:
  A  ext/intl/tests/rangeformatter/rangeformatter_create_error_reset.phpt
  M  NEWS
  M  ext/intl/rangeformatter/rangeformatter_class.cpp


Diff:

diff --git a/NEWS b/NEWS
index b091ea276142..8ea376a2c247 100644
--- a/NEWS
+++ b/NEWS
@@ -46,6 +46,8 @@ PHP                                                                        NEWS
     string. (Weilin Du)
   . Fixed IntlListFormatter::__construct() leaving stale global error state
     after successful calls. (Weilin Du)
+  . Fixed IntlNumberRangeFormatter leaving stale global error state after
+    successful createFromSkeleton() and format() calls. (Weilin Du)
   . Implemented GH-20255 (Add a predefined calendar constant in
     IntlDateFormatter for the proleptic gregorian calendar). (David Carlier)
   . Added SpoofChecker::areBidiConfusable(). (David Carlier)
diff --git a/ext/intl/rangeformatter/rangeformatter_class.cpp b/ext/intl/rangeformatter/rangeformatter_class.cpp
index 2dbb60c5b639..95acfccd2452 100644
--- a/ext/intl/rangeformatter/rangeformatter_class.cpp
+++ b/ext/intl/rangeformatter/rangeformatter_class.cpp
@@ -88,6 +88,8 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton)
     zend_long collapse;
     zend_long identityFallback;
 
+    intl_error_reset(NULL);
+
     ZEND_PARSE_PARAMETERS_START(4,4)
         Z_PARAM_STRING(skeleton, skeleton_len)
         Z_PARAM_STRING(locale, locale_len)
@@ -158,7 +160,10 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format)
     zval *start;
     zval *end;
 
+    intl_error_reset(NULL);
+
     IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS);
+    intl_error_reset(RANGEFORMATTER_ERROR_P(obj));
 
     ZEND_PARSE_PARAMETERS_START(2, 2)
         Z_PARAM_NUMBER(start)
@@ -179,13 +184,13 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format)
     INTL_G(error_level) = 0;
 
     if (U_FAILURE(error)) {
-        intl_error_set(NULL, error, "Failed to format number range");
+        intl_errors_set(RANGEFORMATTER_ERROR_P(obj), error, "Failed to format number range");
     }
 
     zend_string *ret = intl_charFromString(result, &error);
 
     if (U_FAILURE(error)) {
-        intl_error_set(NULL, error, "Failed to convert result to UTF-8");
+        intl_errors_set(RANGEFORMATTER_ERROR_P(obj), error, "Failed to convert result to UTF-8");
     }
 
     INTL_G(use_exceptions) = old_use_exception;
diff --git a/ext/intl/tests/rangeformatter/rangeformatter_create_error_reset.phpt b/ext/intl/tests/rangeformatter/rangeformatter_create_error_reset.phpt
new file mode 100644
index 000000000000..fb19da87d58d
--- /dev/null
+++ b/ext/intl/tests/rangeformatter/rangeformatter_create_error_reset.phpt
@@ -0,0 +1,54 @@
+--TEST--
+IntlNumberRangeFormatter resets stale errors
+--EXTENSIONS--
+intl
+--SKIPIF--
+<?php
+if (version_compare(INTL_ICU_VERSION, '63.0') < 0) {
+    die('skip for ICU < 63.0');
+}
+?>
+--FILE--
+<?php
+try {
+    IntlNumberRangeFormatter::createFromSkeleton(
+        'invalid skeleton here',
+        'en_US',
+        IntlNumberRangeFormatter::COLLAPSE_AUTO,
+        IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE
+    );
+} catch (IntlException $exception) {
+    var_dump(str_contains(intl_get_error_message(), 'U_NUMBER_SKELETON_SYNTAX_ERROR'));
+}
+
+$formatter = IntlNumberRangeFormatter::createFromSkeleton(
+    '',
+    'en_US',
+    IntlNumberRangeFormatter::COLLAPSE_AUTO,
+    IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE
+);
+
+var_dump(intl_get_error_code());
+var_dump(intl_get_error_message());
+
+try {
+    IntlNumberRangeFormatter::createFromSkeleton(
+        'invalid skeleton here',
+        'en_US',
+        IntlNumberRangeFormatter::COLLAPSE_AUTO,
+        IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE
+    );
+} catch (IntlException $exception) {
+}
+
+$formatter->format(1, 2);
+
+var_dump(intl_get_error_code());
+var_dump(intl_get_error_message());
+?>
+--EXPECT--
+bool(true)
+int(0)
+string(12) "U_ZERO_ERROR"
+int(0)
+string(12) "U_ZERO_ERROR"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.