From f1c6357363e6209184fb60ba1d0d5ad4bcb8d358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Sat, 16 May 2026 18:20:07 +0200 Subject: [PATCH 1/3] Deprecate making `__debugInfo()` nullable (#21984) * Deprecate making `__debugInfo()` nullable Returning `null` is already deprecated since PHP 8.5 (3dc962b9f765f5f4a7f8c4fa93f55fee8dad84ca). Not deprecating a corresponding return type seems like an oversight. * NEWS / UPGRADING --- NEWS | 1 + UPGRADING | 4 ++++ Zend/tests/debug_info/debug_info.phpt | 7 +++++++ .../magic_methods/magic_methods_inheritance_rules.phpt | 3 ++- Zend/tests/return_types/042.phpt | 7 ++++++- Zend/zend_API.c | 4 ++++ ext/simplexml/simplexml.stub.php | 2 +- ext/simplexml/simplexml_arginfo.h | 4 ++-- 8 files changed, 27 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 821dc09ad3a1..65b1f85ba378 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,7 @@ PHP NEWS initialization). (Arnaud) . Enabled the TAILCALL VM on Windows when compiling with Clang >= 19 x86_64. (henderkes) + . Deprecate specifying a nullable return type for __debugInfo(). (timwolla) - BCMath: . Added NUL-byte validation to BCMath functions. (jorgsowa) diff --git a/UPGRADING b/UPGRADING index 37abc121a070..de086c600f56 100644 --- a/UPGRADING +++ b/UPGRADING @@ -189,6 +189,10 @@ PHP 8.6 UPGRADE NOTES 4. Deprecated Functionality ======================================== +- Core: + . Specifying a return type of array|null / ?array for __debugInfo() is now + deprecated. Specify array instead. + - GMP . The shift (<<, >>) and exponentiation (**) operators on GMP objects now emit a deprecation warning when converting a float right operand to int diff --git a/Zend/tests/debug_info/debug_info.phpt b/Zend/tests/debug_info/debug_info.phpt index bff5876777ba..e7bb4d48aec6 100644 --- a/Zend/tests/debug_info/debug_info.phpt +++ b/Zend/tests/debug_info/debug_info.phpt @@ -21,6 +21,12 @@ class Bar { } } +class Baz { + public function __debugInfo(): ?array { + return null; + } +} + $f = new Foo; var_dump($f); @@ -28,6 +34,7 @@ $b = new Bar; var_dump($b); ?> --EXPECTF-- +Deprecated: Returning null from Baz::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d object(Foo)#%d (3) { ["a"]=> int(1) diff --git a/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt b/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt index 6bdcafb1bfb5..a4076ee00ce2 100644 --- a/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt +++ b/Zend/tests/magic_methods/magic_methods_inheritance_rules.phpt @@ -66,5 +66,6 @@ class WidenedArgumentType extends NarrowedReturnType { echo 'No problems!'; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning null from ValidMagicMethods::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d No problems! diff --git a/Zend/tests/return_types/042.phpt b/Zend/tests/return_types/042.phpt index 069e0228ff99..21483047d4f2 100644 --- a/Zend/tests/return_types/042.phpt +++ b/Zend/tests/return_types/042.phpt @@ -20,5 +20,10 @@ class JustAnArray { echo 'No problems!'; ?> ---EXPECT-- +--EXPECTF-- +Deprecated: Returning null from UnionType::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d + +Deprecated: Returning null from UnionType2::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d + +Deprecated: Returning null from UnionTypeOldStyle::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead in %s on line %d No problems! diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 004b4fd81e98..65834adbafff 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2825,6 +2825,10 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, zend_check_magic_method_non_static(ce, fptr, error_type); zend_check_magic_method_public(ce, fptr); zend_check_magic_method_return_type(ce, fptr, error_type, (MAY_BE_ARRAY | MAY_BE_NULL)); + if ((fptr->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) && ZEND_TYPE_PURE_MASK(fptr->common.arg_info[-1].type) & MAY_BE_NULL) { + zend_error(E_DEPRECATED, "Returning null from %s::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead", + ZSTR_VAL(ce->name)); + } } else if (zend_string_equals_literal(lcname, "__serialize")) { zend_check_magic_method_args(0, ce, fptr, error_type); zend_check_magic_method_non_static(ce, fptr, error_type); diff --git a/ext/simplexml/simplexml.stub.php b/ext/simplexml/simplexml.stub.php index 935af16621e9..6faf873c885f 100644 --- a/ext/simplexml/simplexml.stub.php +++ b/ext/simplexml/simplexml.stub.php @@ -51,7 +51,7 @@ public function getName(): string {} public function __toString(): string {} - public function __debugInfo(): ?array {} + public function __debugInfo(): array {} /** @tentative-return-type */ public function count(): int {} diff --git a/ext/simplexml/simplexml_arginfo.h b/ext/simplexml/simplexml_arginfo.h index 419c7874fbc5..5a62efbc7be5 100644 --- a/ext/simplexml/simplexml_arginfo.h +++ b/ext/simplexml/simplexml_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit simplexml.stub.php instead. - * Stub hash: cee51320f0f09f14962fb72125ef8ff6073a642a */ + * Stub hash: 83f1bd204b309a4558c1b09128fe29f972f54252 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_simplexml_load_file, 0, 1, SimpleXMLElement, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -79,7 +79,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement___toString, 0, 0, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement___debugInfo, 0, 0, IS_ARRAY, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement___debugInfo, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement_count, 0, 0, IS_LONG, 0) From 10704f079f6087a51e3b579faca00d833141d889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CLamentXU123=E2=80=9D?= <108666168+LamentXU123@users.noreply.github.com> Date: Fri, 15 May 2026 16:18:51 +0800 Subject: [PATCH 2/3] ext/intl: Fix out-of-bounds argument positions in calendar date/time APIs. close GH-22044 --- NEWS | 5 ++ UPGRADING | 3 + ext/intl/calendar/calendar_methods.cpp | 24 ++++---- .../calendar/gregoriancalendar_methods.cpp | 2 +- .../calendar_set_date_out_of_bounds.phpt | 32 +++++++++++ .../calendar_set_date_time_out_of_bounds.phpt | 53 ++++++++++++++++++ .../tests/calendar_set_out_of_bounds.phpt | 55 +++++++++++++++++++ ...iancalendar___construct_out_of_bounds.phpt | 53 ++++++++++++++++++ 8 files changed, 215 insertions(+), 12 deletions(-) create mode 100644 ext/intl/tests/calendar_set_date_out_of_bounds.phpt create mode 100644 ext/intl/tests/calendar_set_date_time_out_of_bounds.phpt create mode 100644 ext/intl/tests/calendar_set_out_of_bounds.phpt create mode 100644 ext/intl/tests/gregoriancalendar___construct_out_of_bounds.phpt diff --git a/NEWS b/NEWS index 8dea2348ff3f..e9392cadf7d4 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,11 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.4.22 +- Intl: + . Fix incorrect argument positions in out-of-bounds errors for + IntlCalendar::set(), IntlCalendar::setDate(), IntlCalendar::setDateTime(), + and IntlGregorianCalendar date/time construction. (Weilin Du) + - MySQLnd: . Fix persistent free of non-persistent connect_attr key (David Carlier). diff --git a/UPGRADING b/UPGRADING index a67fc1b1d88f..466b445c2d11 100644 --- a/UPGRADING +++ b/UPGRADING @@ -82,6 +82,9 @@ PHP 8.4 UPGRADE NOTES . bind_textdomain_codeset, textdomain and d(*)gettext functions now throw an exception if the domain argument is empty. . Intl: + . IntlCalendar::set(), IntlCalendar::setDate(), IntlCalendar::setDateTime(), + and IntlGregorianCalendar date/time construction now report the correct + argument position for out-of-bounds integer values. . resourcebundle_get(), ResourceBundle::get(), and accessing offsets on a ResourceBundle object now throw: - TypeError for invalid offset types diff --git a/ext/intl/calendar/calendar_methods.cpp b/ext/intl/calendar/calendar_methods.cpp index 9b7a37c0df52..61408375c867 100644 --- a/ext/intl/calendar/calendar_methods.cpp +++ b/ext/intl/calendar/calendar_methods.cpp @@ -391,8 +391,8 @@ U_CFUNC PHP_FUNCTION(intlcal_set) } for (int i = 0; i < arg_num; i++) { - /* Arguments start at 1 */ - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(args[i], i + 1); + /* Count from intlcal_set($calendar, ...), so date/time arguments start at #2. */ + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(args[i], i + 2); } CALENDAR_METHOD_FETCH_OBJECT; @@ -427,9 +427,10 @@ U_CFUNC PHP_METHOD(IntlCalendar, setDate) RETURN_THROWS(); } - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 1); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 2); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 3); + /* These method-only APIs parse the object first, so the API argument positions are offset by +1. */ + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 2); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 3); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 4); CALENDAR_METHOD_FETCH_OBJECT; @@ -450,18 +451,19 @@ U_CFUNC PHP_METHOD(IntlCalendar, setDateTime) RETURN_THROWS(); } - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 1); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 2); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 3); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(hour, 4); - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(minute, 5); + /* These method-only APIs parse the object first, so the API argument positions are offset by +1. */ + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(year, 2); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(month, 3); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(day, 4); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(hour, 5); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(minute, 6); CALENDAR_METHOD_FETCH_OBJECT; if (second_is_null) { co->ucal->set((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute); } else { - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 6); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(second, 7); co->ucal->set((int32_t) year, (int32_t) month, (int32_t) day, (int32_t) hour, (int32_t) minute, (int32_t) second); } } diff --git a/ext/intl/calendar/gregoriancalendar_methods.cpp b/ext/intl/calendar/gregoriancalendar_methods.cpp index d6b8f0602dd0..0b36e621ef7f 100644 --- a/ext/intl/calendar/gregoriancalendar_methods.cpp +++ b/ext/intl/calendar/gregoriancalendar_methods.cpp @@ -178,7 +178,7 @@ static void _php_intlgregcal_constructor_body( } else { // From date/time (3, 5 or 6 arguments) for (int i = 0; i < variant; i++) { - ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(largs[i], hasThis() ? (i-1) : i); + ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(largs[i], i + 1); } if (variant == 3) { diff --git a/ext/intl/tests/calendar_set_date_out_of_bounds.phpt b/ext/intl/tests/calendar_set_date_out_of_bounds.phpt new file mode 100644 index 000000000000..db9d18275ae8 --- /dev/null +++ b/ext/intl/tests/calendar_set_date_out_of_bounds.phpt @@ -0,0 +1,32 @@ +--TEST-- +IntlCalendar::setDate(): out-of-bounds arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +setDate(99999999999, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDate(1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDate(1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +IntlCalendar::setDate(): Argument #1 ($year) must be between -2147483648 and 2147483647 +IntlCalendar::setDate(): Argument #2 ($month) must be between -2147483648 and 2147483647 +IntlCalendar::setDate(): Argument #3 ($dayOfMonth) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/calendar_set_date_time_out_of_bounds.phpt b/ext/intl/tests/calendar_set_date_time_out_of_bounds.phpt new file mode 100644 index 000000000000..798ab1ebb01f --- /dev/null +++ b/ext/intl/tests/calendar_set_date_time_out_of_bounds.phpt @@ -0,0 +1,53 @@ +--TEST-- +IntlCalendar::setDateTime(): out-of-bounds arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +setDateTime(99999999999, 1, 1, 1, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 99999999999, 1, 1, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 99999999999, 1, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 1, 99999999999, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->setDateTime(1, 1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +IntlCalendar::setDateTime(): Argument #1 ($year) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #2 ($month) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #3 ($dayOfMonth) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #4 ($hour) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #5 ($minute) must be between -2147483648 and 2147483647 +IntlCalendar::setDateTime(): Argument #6 ($second) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/calendar_set_out_of_bounds.phpt b/ext/intl/tests/calendar_set_out_of_bounds.phpt new file mode 100644 index 000000000000..1ca407d3f713 --- /dev/null +++ b/ext/intl/tests/calendar_set_out_of_bounds.phpt @@ -0,0 +1,55 @@ +--TEST-- +IntlCalendar::set(): out-of-bounds date/time arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +set(99999999999, 1, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + intlcal_set($cal, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->set(1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + $cal->set(1, 1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + intlcal_set($cal, 1, 1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d +IntlCalendar::set(): Argument #1 ($year) must be between -2147483648 and 2147483647 + +Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d +intlcal_set(): Argument #3 ($month) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d +IntlCalendar::set(): Argument #4 ($hour) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlCalendar::set() with more than 2 arguments is deprecated, use either IntlCalendar::setDate() or IntlCalendar::setDateTime() instead in %s on line %d +IntlCalendar::set(): Argument #5 ($minute) must be between -2147483648 and 2147483647 + +Deprecated: Function intlcal_set() is deprecated since 8.4, use IntlCalendar::set(), IntlCalendar::setDate(), or IntlCalendar::setDateTime() instead in %s on line %d +intlcal_set(): Argument #7 ($second) must be between -2147483648 and 2147483647 diff --git a/ext/intl/tests/gregoriancalendar___construct_out_of_bounds.phpt b/ext/intl/tests/gregoriancalendar___construct_out_of_bounds.phpt new file mode 100644 index 000000000000..5b084b25d869 --- /dev/null +++ b/ext/intl/tests/gregoriancalendar___construct_out_of_bounds.phpt @@ -0,0 +1,53 @@ +--TEST-- +IntlGregorianCalendar::__construct(): out-of-bounds date/time arguments report correct positions +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +try { + intlgregcal_create_instance(1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + new IntlGregorianCalendar(1, 1, 1, 99999999999, 1); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + new IntlGregorianCalendar(1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} + +try { + intlgregcal_create_instance(1, 1, 1, 1, 1, 99999999999); +} catch (Throwable $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +IntlGregorianCalendar::__construct(): Argument #1 ($timezoneOrYear) must be between -2147483648 and 2147483647 + +Deprecated: Function intlgregcal_create_instance() is deprecated since 8.4, use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +intlgregcal_create_instance(): Argument #2 ($localeOrMonth) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +IntlGregorianCalendar::__construct(): Argument #4 ($hour) must be between -2147483648 and 2147483647 + +Deprecated: Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated, use either IntlGregorianCalendar::createFromDate() or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +IntlGregorianCalendar::__construct(): Argument #5 ($minute) must be between -2147483648 and 2147483647 + +Deprecated: Function intlgregcal_create_instance() is deprecated since 8.4, use IntlGregorianCalendar::__construct(), IntlGregorianCalendar::createFromDate(), or IntlGregorianCalendar::createFromDateTime() instead in %s on line %d +intlgregcal_create_instance(): Argument #6 ($second) must be between -2147483648 and 2147483647 From d5a57af4e26db810875eb9ea8f00be5c3cda9635 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 15 May 2026 18:26:17 +0100 Subject: [PATCH 3/3] ext/xml: Use zend_string_safe_realloc() for cdata concatenation. The previous code computed `Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value)` as a plain `size_t` addition before passing the result to zend_string_extend(), which can wrap on 32-bit and lead to a heap overflow in the following strncpy(). Switch to zend_string_safe_realloc() so the size computation is bounds-checked. close GH-22056 --- ext/xml/xml.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ext/xml/xml.c b/ext/xml/xml.c index 8394bbf3cb31..5b098f5d91b4 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -828,16 +828,15 @@ void xml_characterDataHandler(void *userData, const XML_Char *s, int len) zval *myval; /* check if the current tag already has a value - if yes append to that! */ if ((myval = zend_hash_find(Z_ARRVAL_P(ctag), ZSTR_KNOWN(ZEND_STR_VALUE))) && Z_TYPE_P(myval) == IS_STRING) { - size_t newlen = Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value); - Z_STR_P(myval) = zend_string_extend(Z_STR_P(myval), newlen, 0); + Z_STR_P(myval) = zend_string_safe_realloc(Z_STR_P(myval), 1, Z_STRLEN_P(myval), ZSTR_LEN(decoded_value), false); strncpy(Z_STRVAL_P(myval) + Z_STRLEN_P(myval) - ZSTR_LEN(decoded_value), ZSTR_VAL(decoded_value), ZSTR_LEN(decoded_value) + 1); - zend_string_release_ex(decoded_value, 0); + zend_string_release_ex(decoded_value, false); } else { if (doprint || (! parser->skipwhite)) { add_assoc_str(ctag, "value", decoded_value); } else { - zend_string_release_ex(decoded_value, 0); + zend_string_release_ex(decoded_value, false); } } } else { @@ -855,11 +854,10 @@ void xml_characterDataHandler(void *userData, const XML_Char *s, int len) if (EXPECTED(Z_TYPE_P(mytype) == IS_STRING) && zend_string_equals_literal(Z_STR_P(mytype), "cdata")) { SEPARATE_ARRAY(curtag); if ((myval = zend_hash_find(Z_ARRVAL_P(curtag), ZSTR_KNOWN(ZEND_STR_VALUE)))) { - size_t newlen = Z_STRLEN_P(myval) + ZSTR_LEN(decoded_value); - Z_STR_P(myval) = zend_string_extend(Z_STR_P(myval), newlen, 0); + Z_STR_P(myval) = zend_string_safe_realloc(Z_STR_P(myval), 1, Z_STRLEN_P(myval), ZSTR_LEN(decoded_value), false); strncpy(Z_STRVAL_P(myval) + Z_STRLEN_P(myval) - ZSTR_LEN(decoded_value), ZSTR_VAL(decoded_value), ZSTR_LEN(decoded_value) + 1); - zend_string_release_ex(decoded_value, 0); + zend_string_release_ex(decoded_value, false); return; } } @@ -877,7 +875,7 @@ void xml_characterDataHandler(void *userData, const XML_Char *s, int len) } else if (parser->level == (XML_MAXLEVEL + 1)) { php_error_docref(NULL, E_WARNING, "Maximum depth exceeded - Results truncated"); } else { - zend_string_release_ex(decoded_value, 0); + zend_string_release_ex(decoded_value, false); } } }