From 97402d5ab58018c90e9a80495c12fc423990dcce Mon Sep 17 00:00:00 2001 From: bogdanungureanu Date: Wed, 5 Mar 2025 13:04:09 +0200 Subject: [PATCH 1/6] ext/intl: Add DECIMAL_COMPACT_SHORT and DECIMAL_COMPACT_LONG for NumberFormatter class close GH-17975 --- ext/intl/formatter/formatter.stub.php | 4 ++ ext/intl/formatter/formatter_arginfo.h | 14 ++++- .../formatter_format_decimal_compact.phpt | 57 +++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 ext/intl/tests/formatter_format_decimal_compact.phpt diff --git a/ext/intl/formatter/formatter.stub.php b/ext/intl/formatter/formatter.stub.php index e335698688d64..4445005c41705 100644 --- a/ext/intl/formatter/formatter.stub.php +++ b/ext/intl/formatter/formatter.stub.php @@ -11,6 +11,10 @@ class NumberFormatter public const int PATTERN_DECIMAL = UNKNOWN; /** @cvalue UNUM_DECIMAL */ public const int DECIMAL = UNKNOWN; + /** @cvalue UNUM_DECIMAL_COMPACT_SHORT */ + public const int DECIMAL_COMPACT_SHORT = UNKNOWN; + /** @cvalue UNUM_DECIMAL_COMPACT_LONG */ + public const int DECIMAL_COMPACT_LONG = UNKNOWN; /** @cvalue UNUM_CURRENCY */ public const int CURRENCY = UNKNOWN; /** @cvalue UNUM_PERCENT */ diff --git a/ext/intl/formatter/formatter_arginfo.h b/ext/intl/formatter/formatter_arginfo.h index 0e3d8b797e721..c7fd28c3a9f77 100644 --- a/ext/intl/formatter/formatter_arginfo.h +++ b/ext/intl/formatter/formatter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: caaa6ff408bfd88ec9bb998ffd753f4de971ccff */ + * Stub hash: 05ab9fb3ba33163b2100e2773d70f67e110ecefc */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_NumberFormatter___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) @@ -137,6 +137,18 @@ static zend_class_entry *register_class_NumberFormatter(void) zend_declare_typed_class_constant(class_entry, const_DECIMAL_name, &const_DECIMAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(const_DECIMAL_name); + zval const_DECIMAL_COMPACT_SHORT_value; + ZVAL_LONG(&const_DECIMAL_COMPACT_SHORT_value, UNUM_DECIMAL_COMPACT_SHORT); + zend_string *const_DECIMAL_COMPACT_SHORT_name = zend_string_init_interned("DECIMAL_COMPACT_SHORT", sizeof("DECIMAL_COMPACT_SHORT") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_DECIMAL_COMPACT_SHORT_name, &const_DECIMAL_COMPACT_SHORT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_DECIMAL_COMPACT_SHORT_name); + + zval const_DECIMAL_COMPACT_LONG_value; + ZVAL_LONG(&const_DECIMAL_COMPACT_LONG_value, UNUM_DECIMAL_COMPACT_LONG); + zend_string *const_DECIMAL_COMPACT_LONG_name = zend_string_init_interned("DECIMAL_COMPACT_LONG", sizeof("DECIMAL_COMPACT_LONG") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_DECIMAL_COMPACT_LONG_name, &const_DECIMAL_COMPACT_LONG_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_DECIMAL_COMPACT_LONG_name); + zval const_CURRENCY_value; ZVAL_LONG(&const_CURRENCY_value, UNUM_CURRENCY); zend_string *const_CURRENCY_name = zend_string_init_interned("CURRENCY", sizeof("CURRENCY") - 1, 1); diff --git a/ext/intl/tests/formatter_format_decimal_compact.phpt b/ext/intl/tests/formatter_format_decimal_compact.phpt new file mode 100644 index 0000000000000..2c78f8787e0f4 --- /dev/null +++ b/ext/intl/tests/formatter_format_decimal_compact.phpt @@ -0,0 +1,57 @@ +--TEST-- +numfmt_format_currency() icu >= 4.8 +--EXTENSIONS-- +intl +--FILE-- + +--EXPECTF-- +en_UK: short = 1.2M +en_UK: long = 1.2 million +en_US: short = 1.2M +en_US: long = 1.2 million +ru: short = 1,2 млн +ru: long = 1,2 миллиона +zh_CN: short = 123万 +zh_CN: long = 123万 +ro: short = 1,2 mil. +ro: long = 1,2 milioane +uk: short = 1,2 млн +uk: long = 1,2 мільйона +en: short = 1.2M +en: long = 1.2 million +bg: short = 1,2 млн. +bg: long = 1,2 милиона \ No newline at end of file From cd88e9f1f4424b47b876ee1ad1161d3f53e7f912 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 7 Mar 2025 18:02:52 +0000 Subject: [PATCH 2/6] [skip ci] NEWS/UPGRADING --- NEWS | 2 ++ UPGRADING | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/NEWS b/NEWS index cf57d0a36b676..68e7df9d84f7f 100644 --- a/NEWS +++ b/NEWS @@ -58,6 +58,8 @@ PHP NEWS . Bumped ICU requirement to ICU >= 57.1. (cmb) . IntlDateFormatter::setTimeZone()/datefmt_set_timezone() throws an exception with uninitialised classes or clone failure. (David Carlier) + . Added DECIMAL_COMPACT_SHORT/DECIMAL_COMPACT_LONG for NumberFormatter class. + (BogdanUngureanu) - MySQLi: . Fixed bugs GH-17900 and GH-8084 (calling mysqli::__construct twice). diff --git a/UPGRADING b/UPGRADING index 4129c7349444a..21cf4d3062df7 100644 --- a/UPGRADING +++ b/UPGRADING @@ -291,6 +291,10 @@ PHP 8.5 UPGRADE NOTES . CURLINFO_HTTPAUTH_USED. . CURLINFO_PROXYAUTH_USED. +- Intl: + . DECIMAL_COMPACT_SHORT. + . DECIMAL_COMPACT_LONG. + - POSIX: . POSIX_SC_OPEN_MAX. From 07ceadf7d9bcb398fd3b3befa9fdf0df3a96dc8d Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 6 Mar 2025 22:26:34 +0000 Subject: [PATCH 3/6] Fix GH-17984: gd calls with array arguments. close GH-17985 --- NEWS | 2 ++ ext/gd/gd.c | 8 +++---- ext/gd/tests/gh17984.phpt | 44 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 ext/gd/tests/gh17984.phpt diff --git a/NEWS b/NEWS index 352dce95e7a42..d72d262bbc42c 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,8 @@ PHP NEWS - GD: . Fixed bug GH-17772 (imagepalettetotruecolor crash with memory_limit=2M). (David Carlier) + . Fixed bug GH-17984 (calls with arguments as array with references). + (David Carlier) - LDAP: . Fixed bug GH-17704 (ldap_search fails when $attributes contains a diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 847e0835bad4f..2585923edcc22 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -3417,7 +3417,7 @@ PHP_FUNCTION(imageconvolution) } for (i=0; i<3; i++) { - if ((var = zend_hash_index_find(Z_ARRVAL_P(hash_matrix), (i))) != NULL && Z_TYPE_P(var) == IS_ARRAY) { + if ((var = zend_hash_index_find_deref(Z_ARRVAL_P(hash_matrix), (i))) != NULL && Z_TYPE_P(var) == IS_ARRAY) { if (zend_hash_num_elements(Z_ARRVAL_P(var)) != 3 ) { zend_argument_value_error(2, "must be a 3x3 array, matrix[%d] only has %d elements", i, zend_hash_num_elements(Z_ARRVAL_P(var))); RETURN_THROWS(); @@ -3697,7 +3697,7 @@ PHP_FUNCTION(imageaffine) } for (i = 0; i < nelems; i++) { - if ((zval_affine_elem = zend_hash_index_find(Z_ARRVAL_P(z_affine), i)) != NULL) { + if ((zval_affine_elem = zend_hash_index_find_deref(Z_ARRVAL_P(z_affine), i)) != NULL) { switch (Z_TYPE_P(zval_affine_elem)) { case IS_LONG: affine[i] = Z_LVAL_P(zval_affine_elem); @@ -3873,7 +3873,7 @@ PHP_FUNCTION(imageaffinematrixconcat) } for (i = 0; i < 6; i++) { - if ((tmp = zend_hash_index_find(Z_ARRVAL_P(z_m1), i)) != NULL) { + if ((tmp = zend_hash_index_find_deref(Z_ARRVAL_P(z_m1), i)) != NULL) { switch (Z_TYPE_P(tmp)) { case IS_LONG: m1[i] = Z_LVAL_P(tmp); @@ -3890,7 +3890,7 @@ PHP_FUNCTION(imageaffinematrixconcat) } } - if ((tmp = zend_hash_index_find(Z_ARRVAL_P(z_m2), i)) != NULL) { + if ((tmp = zend_hash_index_find_deref(Z_ARRVAL_P(z_m2), i)) != NULL) { switch (Z_TYPE_P(tmp)) { case IS_LONG: m2[i] = Z_LVAL_P(tmp); diff --git a/ext/gd/tests/gh17984.phpt b/ext/gd/tests/gh17984.phpt new file mode 100644 index 0000000000000..c46c455799e0f --- /dev/null +++ b/ext/gd/tests/gh17984.phpt @@ -0,0 +1,44 @@ +--TEST-- +GH-17984: array of references handling +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +object(GdImage)#2 (0) { +} +array(6) { + [0]=> + float(2028) + [1]=> + float(46) + [2]=> + float(138) + [3]=> + float(4) + [4]=> + float(233) + [5]=> + float(7) +} +bool(true) +bool(true) +bool(true) From fc09eb21db722cc31cea0a8687c9bfdb05bb1218 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 7 Mar 2025 18:31:00 +0000 Subject: [PATCH 4/6] [skip ci] fix NEWS entry --- NEWS | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index d72d262bbc42c..46b0934b8700e 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.3.19 +- GD: + . Fixed bug GH-17984 (calls with arguments as array with references). + (David Carlier) + - Treewide: . Fixed bug GH-17736 (Assertion failure zend_reference_destroy()). (nielsdos) @@ -34,8 +38,6 @@ PHP NEWS - GD: . Fixed bug GH-17772 (imagepalettetotruecolor crash with memory_limit=2M). (David Carlier) - . Fixed bug GH-17984 (calls with arguments as array with references). - (David Carlier) - LDAP: . Fixed bug GH-17704 (ldap_search fails when $attributes contains a From 6083dc09a3d760074941c17e7eb10e606768a5fe Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 7 Mar 2025 17:37:40 +0100 Subject: [PATCH 5/6] Fix GH-17991: Assertion failure dom_attr_value_write Closes GH-17995. --- NEWS | 3 +++ ext/dom/php_dom.c | 7 ++++--- ext/dom/tests/gh17991.phpt | 28 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 ext/dom/tests/gh17991.phpt diff --git a/NEWS b/NEWS index 77446730edb4c..34f75683d7170 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,9 @@ PHP NEWS . Fixed bug GH-17913 (ReflectionFunction::isDeprecated() returns incorrect results for closures created from magic __call()). (timwolla) +- DOM: + . Fixed bug GH-17991 (Assertion failure dom_attr_value_write). (nielsdos) + - Opcache: . Fixed bug GH-15834 (Segfault with hook "simple get" cache slot and minimal JIT). (nielsdos) diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index f84f17fee2e9b..819d22712ebfc 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -372,13 +372,14 @@ static zend_always_inline const dom_prop_handler *dom_get_prop_handler(const dom if (obj->prop_handler != NULL) { if (cache_slot && *cache_slot == obj->prop_handler) { - hnd = *(cache_slot + 1); + hnd = cache_slot[1]; } if (!hnd) { hnd = zend_hash_find_ptr(obj->prop_handler, name); if (cache_slot) { - *cache_slot = obj->prop_handler; - *(cache_slot + 1) = (void *) hnd; + cache_slot[0] = obj->prop_handler; + cache_slot[1] = (void *) hnd; + cache_slot[2] = NULL; } } } diff --git a/ext/dom/tests/gh17991.phpt b/ext/dom/tests/gh17991.phpt new file mode 100644 index 0000000000000..4fc2c5b4ec1eb --- /dev/null +++ b/ext/dom/tests/gh17991.phpt @@ -0,0 +1,28 @@ +--TEST-- +GH-17991 (Assertion failure dom_attr_value_write) +--EXTENSIONS-- +dom +--FILE-- +value = new Test); +} +$box = new Box(); +test($box); +test($attr); +?> +--EXPECTF-- +object(Test)#%d (0) { +} + +Fatal error: Uncaught TypeError: Cannot assign Test to property DOMAttr::$value of type string in %s:%d +Stack trace: +#0 %s(%d): test(Object(DOMAttr)) +#1 {main} + thrown in %s on line %d From 38e8725becf71a9cbd1fc8e8163b69ee1e2eb0d6 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:56:39 +0100 Subject: [PATCH 6/6] Fix GH-17941: Stack-use-after-return with lazy objects and hooks zend_std_write_property() can return the variable pointer, but the code was using a local variable, and so a pointer to a local variable could be returned. Fix this by using the value pointer instead of the backup value was written. This can be more efficient on master by using the safe_assign helper. Closes GH-17947. --- NEWS | 2 ++ Zend/tests/lazy_objects/gh17941.phpt | 26 ++++++++++++++++++++++++++ Zend/zend_object_handlers.c | 5 +++++ 3 files changed, 33 insertions(+) create mode 100644 Zend/tests/lazy_objects/gh17941.phpt diff --git a/NEWS b/NEWS index 34f75683d7170..576a045a02294 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ PHP NEWS child class). (ilutov) . Fixed bug GH-17913 (ReflectionFunction::isDeprecated() returns incorrect results for closures created from magic __call()). (timwolla) + . Fixed bug GH-17941 (Stack-use-after-return with lazy objects and hooks). + (nielsdos) - DOM: . Fixed bug GH-17991 (Assertion failure dom_attr_value_write). (nielsdos) diff --git a/Zend/tests/lazy_objects/gh17941.phpt b/Zend/tests/lazy_objects/gh17941.phpt new file mode 100644 index 0000000000000..6af6355b99573 --- /dev/null +++ b/Zend/tests/lazy_objects/gh17941.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-17941 (Stack-use-after-return with lazy objects and hooks) +--FILE-- + $this->prop; set($x) => $this->prop = $x;} +} + +$rc = new ReflectionClass(SubClass::class); +$obj = $rc->newLazyProxy(function ($object) { + echo "init\n"; + return new SubClass; +}); + +function foo(SubClass $x) { + $x->prop = 1; + var_dump($x->prop); +} + +foo($obj); + +?> +--EXPECT-- +init +int(1) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 5a4e4b3ea3a1c..bba40c6bd41ec 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1198,6 +1198,11 @@ lazy_init:; variable_ptr = zend_std_write_property(zobj, name, &backup, cache_slot); zval_ptr_dtor(&backup); + + if (variable_ptr == &backup) { + variable_ptr = value; + } + return variable_ptr; } /* }}} */