From 9e68cf888ac8c8620349d684495c3c4ed52daabe Mon Sep 17 00:00:00 2001 From: Weilin Du <108666168+LamentXU123@users.noreply.github.com> Date: Fri, 12 Jun 2026 22:55:03 +0800 Subject: [PATCH 1/4] ext/intl: Sync IntlTimeZone object errors for invalid display types Align IntlTimeZone::getDisplayName() object error handling for invalid display types with the corresponding IntlDateFormatter behavior, and add coverage for the invalid enum values. Closes GH-22270. --- NEWS | 2 ++ ext/intl/tests/timezone_getDisplayName_error.phpt | 6 ++++++ ext/intl/timezone/timezone_methods.cpp | 6 +++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index faeb27fdf6df..800423779d11 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,8 @@ PHP NEWS . Fix incorrect argument positions for uninitialized calendar arguments in IntlCalendar::equals(), ::before(), ::after(), and ::isEquivalentTo(). (Weilin Du) + . Fixed IntlTimeZone::getDisplayName() to synchronize object error state + for invalid display types. (Weilin Du) . Fixed Spoofchecker restriction-level APIs to only be exposed with ICU 53 and later. (Graham Campbell) diff --git a/ext/intl/tests/timezone_getDisplayName_error.phpt b/ext/intl/tests/timezone_getDisplayName_error.phpt index ce3ab2f7e766..8cecb40ecfea 100644 --- a/ext/intl/tests/timezone_getDisplayName_error.phpt +++ b/ext/intl/tests/timezone_getDisplayName_error.phpt @@ -8,12 +8,18 @@ ini_set("intl.error_level", E_WARNING); $tz = IntlTimeZone::createTimeZone('Europe/Lisbon'); var_dump($tz->getDisplayName(false, -1)); +echo intl_get_error_message(), PHP_EOL; +var_dump($tz->getErrorCode()); +echo $tz->getErrorMessage(), PHP_EOL; var_dump(intltz_get_display_name(null, IntlTimeZone::DISPLAY_SHORT, false, 'pt_PT')); ?> --EXPECTF-- Warning: IntlTimeZone::getDisplayName(): wrong display type in %s on line %d bool(false) +wrong display type: U_ILLEGAL_ARGUMENT_ERROR +int(1) +wrong display type: U_ILLEGAL_ARGUMENT_ERROR Fatal error: Uncaught TypeError: intltz_get_display_name(): Argument #1 ($timezone) must be of type IntlTimeZone, null given in %s:%d Stack trace: diff --git a/ext/intl/timezone/timezone_methods.cpp b/ext/intl/timezone/timezone_methods.cpp index ec7ad9942fd8..e3aa958508c1 100644 --- a/ext/intl/timezone/timezone_methods.cpp +++ b/ext/intl/timezone/timezone_methods.cpp @@ -513,13 +513,15 @@ U_CFUNC PHP_FUNCTION(intltz_get_display_name) RETURN_THROWS(); } + TIMEZONE_METHOD_FETCH_OBJECT; + bool found = false; for (int i = 0; !found && i < sizeof(display_types)/sizeof(*display_types); i++) { if (display_types[i] == display_type) found = true; } if (!found) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + intl_errors_set(TIMEZONE_ERROR_P(to), U_ILLEGAL_ARGUMENT_ERROR, "wrong display type", 0); RETURN_FALSE; } @@ -528,8 +530,6 @@ U_CFUNC PHP_FUNCTION(intltz_get_display_name) locale_str = intl_locale_get_default(); } - TIMEZONE_METHOD_FETCH_OBJECT; - UnicodeString result; to->utimezone->getDisplayName((UBool)daylight, (TimeZone::EDisplayType)display_type, Locale::createFromName(locale_str), result); From 2869551e62c5a177a14b4907738d147764351c9d Mon Sep 17 00:00:00 2001 From: Paul Menzel Date: Fri, 12 Jun 2026 17:04:46 +0200 Subject: [PATCH 2/4] sapi/apache2handler: Add --disable-apache2-conf configure option (#22095) Add a new --disable-apache2-conf option that prevents apxs from editing httpd.conf during installation. When SYSCONFDIR is non-empty, apxs is invoked with -a, which requires httpd.conf to exist at the target path. This fails when installing into a staging directory (INSTALL_ROOT) where no `httpd.conf` exists but apxs is present and works, and is also unwanted on distributions [like Debian][1] that manage Apache module activation separately (e.g. via a2enmod). [1]: https://salsa.debian.org/php-team/php/-/blob/9bd72dc78216cf136315d765ec3a602ac99e60e3/debian/patches/0030-Add-patch-to-install-php7-module-directly-to-APXS_LI.patch Assisted-by: Claude Sonnet 4.6 --- sapi/apache2handler/config.m4 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4 index e335721f19e9..3001a4d61d9a 100644 --- a/sapi/apache2handler/config.m4 +++ b/sapi/apache2handler/config.m4 @@ -6,6 +6,15 @@ PHP_ARG_WITH([apxs2], [no], [no]) +PHP_ARG_ENABLE([apache2-conf], + [whether to activate the PHP module in Apache httpd.conf via apxs], + [AS_HELP_STRING([--disable-apache2-conf], + [Do not activate the PHP module in the Apache httpd.conf during installation + via apxs. Useful when installing into a staging directory or when Apache + configuration is managed separately (e.g., via a2enmod).])], + [yes], + [no]) + if test "$PHP_APXS2" != "no"; then AS_VAR_IF([PHP_APXS2], [yes], [ APXS=apxs @@ -69,7 +78,7 @@ if test "$PHP_APXS2" != "no"; then [AC_MSG_ERROR([Please note that Apache version >= 2.4 is required])]) APXS_LIBEXECDIR='$(INSTALL_ROOT)'$($APXS -q LIBEXECDIR) - if test -z $($APXS -q SYSCONFDIR); then + if test -z $($APXS -q SYSCONFDIR) || test "$PHP_APACHE2_CONF" = "no"; then INSTALL_IT="\$(mkinstalldirs) '$APXS_LIBEXECDIR' && \ $APXS -S LIBEXECDIR='$APXS_LIBEXECDIR' \ -i -n php" From 5c5c48f19ae1fdfc12ea5fdb7ee0fba848dc100f Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Fri, 12 Jun 2026 17:06:49 +0200 Subject: [PATCH 3/4] Add info about --disable-apache2-conf [skip ci] --- UPGRADING.INTERNALS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index c340ba64833c..dd4b9840aee3 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -135,6 +135,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES . --with-pic is now --enable-pic. The old flag will result in an error. . Symbol HAVE_ST_BLOCKS has been removed from php_config.h (use HAVE_STRUCT_STAT_ST_BLOCKS). + . Added a new configure option --disable-apache2-conf to prevent apxs from + editing httpd.conf during installation. - Windows build system changes: . Function SETUP_OPENSSL() doesn't accept 6th argument anymore and doesn't From b50b30c15ea0ba94ab7217dee8e362039600efae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 12 Jun 2026 22:03:27 +0200 Subject: [PATCH 4/4] standard: Fail unserialization when the `C` format is used for classes that are not `Serializable` (#22058) Fixes https://github.com/php/php-src/issues/22046 --- NEWS | 3 +++ .../serialize/serialization_objects_009.phpt | 17 ++++++++--------- ext/standard/var_unserializer.re | 2 +- ext/uri/tests/gh22046.phpt | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 ext/uri/tests/gh22046.phpt diff --git a/NEWS b/NEWS index c6fa558db81e..ac3381900831 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,9 @@ PHP NEWS . Deprecate specifying a nullable return type for __debugInfo(). (timwolla) . Fixed bug GH-22142 (Assertion failure in zendi_try_get_long() on IS_UNDEF). (David Carlier) + . Fixed bug GH-22046 (The unserialize function can lead to segfault when + non-Serializable internal classes are serialized back with the C format). + (kocsismate) - BCMath: . Added NUL-byte validation to BCMath functions. (jorgsowa) diff --git a/ext/standard/tests/serialize/serialization_objects_009.phpt b/ext/standard/tests/serialize/serialization_objects_009.phpt index 9485f3ef8068..95b85ccd80f7 100644 --- a/ext/standard/tests/serialize/serialization_objects_009.phpt +++ b/ext/standard/tests/serialize/serialization_objects_009.phpt @@ -8,17 +8,16 @@ eval('class C {}'); $b = unserialize($ser); var_dump($a, $b); - echo "Done"; ?> --EXPECTF-- -Warning: Class __PHP_Incomplete_Class has no unserializer in %sserialization_objects_009.php on line %d +Warning: Class __PHP_Incomplete_Class has no unserializer in %s on line %d + +Warning: unserialize(): Error at offset 11 of 18 bytes in %s on line %d + +Warning: Class C has no unserializer in %s on line %d -Warning: Class C has no unserializer in %sserialization_objects_009.php on line %d -object(__PHP_Incomplete_Class)#%d (1) { - ["__PHP_Incomplete_Class_Name"]=> - string(1) "C" -} -object(C)#%d (0) { -} +Warning: unserialize(): Error at offset 11 of 18 bytes in %s on line %d +bool(false) +bool(false) Done diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index d5019d94dc0c..484cb5aa8fc9 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -770,7 +770,7 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce) if (ce->unserialize == NULL) { zend_error(E_WARNING, "Class %s has no unserializer", ZSTR_VAL(ce->name)); - object_init_ex(rval, ce); + return 0; } else if (ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash) != SUCCESS) { return 0; } diff --git a/ext/uri/tests/gh22046.phpt b/ext/uri/tests/gh22046.phpt new file mode 100644 index 000000000000..af297905aa30 --- /dev/null +++ b/ext/uri/tests/gh22046.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-22046: The unserialize function can lead to segfault when internal classes are serialized back with the unsupported C format +--FILE-- + +--EXPECTF-- +Warning: Class Uri\WhatWg\Url has no unserializer in %s on line %d + +Warning: unserialize(): Error at offset 25 of 26 bytes in %s on line %d + +Warning: Class Uri\Rfc3986\Uri has no unserializer in %s on line %d + +Warning: unserialize(): Error at offset 26 of 27 bytes in %s on line %d