From 352585249318445f02cff5fcc761f2ea6aa028ab Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Mon, 24 Aug 2026 10:51:55 -0400 Subject: [PATCH] [intl] Add unconstructed-object guard to Collator attribute methods Collator::getAttribute(), setAttribute(), getStrength() and setStrength() dereferenced a NULL ICU collator when invoked on an object whose constructor skipped parent::__construct(), silently returning bogus values or crashing, while compare(), getLocale(), sort() and getSortKey() already throw 'Object not initialized'. Apply the same guard to the four attribute/strength methods; sibling audit found no other Collator methods touching co->ucoll without a check. --- ext/intl/collator/collator_attr.c | 36 ++++++++++++++++ .../collator_attribute_unconstructed.phpt | 42 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 ext/intl/tests/collator_attribute_unconstructed.phpt diff --git a/ext/intl/collator/collator_attr.c b/ext/intl/collator/collator_attr.c index f16ae0cc5285..ac66fb9b3102 100644 --- a/ext/intl/collator/collator_attr.c +++ b/ext/intl/collator/collator_attr.c @@ -40,6 +40,15 @@ PHP_FUNCTION( collator_get_attribute ) /* Fetch the object. */ COLLATOR_METHOD_FETCH_OBJECT; + if (!co || !co->ucoll) { + intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), + "Object not initialized", 0 ); + zend_throw_error(NULL, "Object not initialized"); + + RETURN_THROWS(); + } + value = ucol_getAttribute( co->ucoll, attribute, COLLATOR_ERROR_CODE_P( co ) ); COLLATOR_CHECK_STATUS( co, "Error getting attribute value" ); @@ -64,6 +73,15 @@ PHP_FUNCTION( collator_set_attribute ) /* Fetch the object. */ COLLATOR_METHOD_FETCH_OBJECT; + if (!co || !co->ucoll) { + intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), + "Object not initialized", 0 ); + zend_throw_error(NULL, "Object not initialized"); + + RETURN_THROWS(); + } + /* Set new value for the given attribute. */ ucol_setAttribute( co->ucoll, attribute, value, COLLATOR_ERROR_CODE_P( co ) ); COLLATOR_CHECK_STATUS( co, "Error setting attribute value" ); @@ -87,6 +105,15 @@ PHP_FUNCTION( collator_get_strength ) /* Fetch the object. */ COLLATOR_METHOD_FETCH_OBJECT; + if (!co || !co->ucoll) { + intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), + "Object not initialized", 0 ); + zend_throw_error(NULL, "Object not initialized"); + + RETURN_THROWS(); + } + /* Get current strength and return it. */ RETURN_LONG( ucol_getStrength( co->ucoll ) ); } @@ -109,6 +136,15 @@ PHP_FUNCTION( collator_set_strength ) /* Fetch the object. */ COLLATOR_METHOD_FETCH_OBJECT; + if (!co || !co->ucoll) { + intl_error_set_code( NULL, COLLATOR_ERROR_CODE( co ) ); + intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ), + "Object not initialized", 0 ); + zend_throw_error(NULL, "Object not initialized"); + + RETURN_THROWS(); + } + /* Set given strength. */ ucol_setStrength( co->ucoll, strength ); diff --git a/ext/intl/tests/collator_attribute_unconstructed.phpt b/ext/intl/tests/collator_attribute_unconstructed.phpt new file mode 100644 index 000000000000..915514161308 --- /dev/null +++ b/ext/intl/tests/collator_attribute_unconstructed.phpt @@ -0,0 +1,42 @@ +--TEST-- +Collator attribute and strength methods on unconstructed object +--EXTENSIONS-- +intl +--FILE-- +getAttribute(Collator::NUMERIC_COLLATION)); +} catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; +} + +try { + var_dump($c->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON)); +} catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; +} + +try { + var_dump($c->getStrength()); +} catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; +} + +try { + var_dump($c->setStrength(Collator::SECONDARY)); +} catch (Error $e) { + echo get_class($e), ": ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Error: Object not initialized +Error: Object not initialized +Error: Object not initialized +Error: Object not initialized