From cbd71cb84d566de796450226f74d07d2a61788b9 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 7 Apr 2026 08:31:06 -0700 Subject: [PATCH 1/5] ext/standard: "double" is not deprecated for `settype()` (#20694) Remove incorrect inline comment that using "double" as the type is deprecated; this comment was added in 929ae94c64c71fcbed8e4cecdb6d09398d61e079 when support for "float" was included, but the use of "double" was never actually deprecated. [skip ci] --- ext/standard/type.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/type.c b/ext/standard/type.c index a228e899046f..e23e4620da23 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -105,7 +105,7 @@ PHP_FUNCTION(settype) convert_to_long(ptr); } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_FLOAT))) { convert_to_double(ptr); - } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_DOUBLE))) { /* deprecated */ + } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_DOUBLE))) { convert_to_double(ptr); } else if (zend_string_equals_ci(type, ZSTR_KNOWN(ZEND_STR_STRING))) { convert_to_string(ptr); From 3dab58591220c6b4da6c10755f47f11bde74a2b4 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Tue, 7 Apr 2026 11:50:39 -0400 Subject: [PATCH 2/5] Fix GH-16811: Crash in zend_test observer on runtime observe_function_names change (GH-21635) OnUpdateCommaList called zend_observer_remove/add_begin_handler without checking whether observer data was initialized. This null-dereferenced when the function had never been called (no runtime cache), and hit ZEND_UNREACHABLE() when observe_all had already installed the same handler. Guard both the remove and add blocks with runtime cache checks. Remove existing handlers before re-adding to prevent slot overflow from duplicates. Fixes GH-16811 --- ext/zend_test/observer.c | 9 +++++++-- ext/zend_test/tests/gh16811.phpt | 18 ++++++++++++++++++ ext/zend_test/tests/gh16811_observe_all.phpt | 17 +++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 ext/zend_test/tests/gh16811.phpt create mode 100644 ext/zend_test/tests/gh16811_observe_all.phpt diff --git a/ext/zend_test/observer.c b/ext/zend_test/observer.c index 85c7d82da0e8..e348987359b9 100644 --- a/ext/zend_test/observer.c +++ b/ext/zend_test/observer.c @@ -334,7 +334,8 @@ static ZEND_INI_MH(zend_test_observer_OnUpdateCommaList) } if (stage != PHP_INI_STAGE_STARTUP && stage != PHP_INI_STAGE_ACTIVATE && stage != PHP_INI_STAGE_DEACTIVATE && stage != PHP_INI_STAGE_SHUTDOWN) { ZEND_HASH_FOREACH_STR_KEY(*p, funcname) { - if ((func = zend_hash_find_ptr(EG(function_table), funcname))) { + if ((func = zend_hash_find_ptr(EG(function_table), funcname)) + && RUN_TIME_CACHE(&func->common)) { void *old_handler; zend_observer_remove_begin_handler(func, observer_begin, (zend_observer_fcall_begin_handler *)&old_handler); zend_observer_remove_end_handler(func, observer_end, (zend_observer_fcall_end_handler *)&old_handler); @@ -357,7 +358,11 @@ static ZEND_INI_MH(zend_test_observer_OnUpdateCommaList) zend_string_release(str); if (stage != PHP_INI_STAGE_STARTUP && stage != PHP_INI_STAGE_ACTIVATE && stage != PHP_INI_STAGE_DEACTIVATE && stage != PHP_INI_STAGE_SHUTDOWN) { ZEND_HASH_FOREACH_STR_KEY(*p, funcname) { - if ((func = zend_hash_find_ptr(EG(function_table), funcname))) { + if ((func = zend_hash_find_ptr(EG(function_table), funcname)) + && RUN_TIME_CACHE(&func->common) && *ZEND_OBSERVER_DATA(func)) { + void *old_handler; + zend_observer_remove_begin_handler(func, observer_begin, (zend_observer_fcall_begin_handler *)&old_handler); + zend_observer_remove_end_handler(func, observer_end, (zend_observer_fcall_end_handler *)&old_handler); zend_observer_add_begin_handler(func, observer_begin); zend_observer_add_end_handler(func, observer_end); } diff --git a/ext/zend_test/tests/gh16811.phpt b/ext/zend_test/tests/gh16811.phpt new file mode 100644 index 000000000000..1b2b8ece9aa1 --- /dev/null +++ b/ext/zend_test/tests/gh16811.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-16811 (Segmentation fault in zend observer) +--EXTENSIONS-- +zend_test +--INI-- +zend_test.observer.enabled=1 +zend_test.observer.show_output=1 +zend_test.observer.observe_function_names=a,d +--FILE-- + +--EXPECTF-- + + + +string(3) "a,d" diff --git a/ext/zend_test/tests/gh16811_observe_all.phpt b/ext/zend_test/tests/gh16811_observe_all.phpt new file mode 100644 index 000000000000..466aa0c6d4a4 --- /dev/null +++ b/ext/zend_test/tests/gh16811_observe_all.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-16811 (Assertion failure adding duplicate observer handler) +--EXTENSIONS-- +zend_test +--INI-- +zend_test.observer.enabled=1 +zend_test.observer.observe_all=1 +zend_test.observer.show_output=0 +--FILE-- + +--EXPECT-- +Done From 5bdfb1c5e64269db8ffa8962d2c9fc0c0bc4ed60 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 7 Apr 2026 18:07:42 +0200 Subject: [PATCH 3/5] [skip ci] Move gcovr options to config file (GH-21663) Having these in the make file is very annoying, because it requires rebuilding from scratch and rerunning tests just to see if some flag is effective. --- build/Makefile.gcov | 25 ++----------------------- gcovr.cfg | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 23 deletions(-) create mode 100644 gcovr.cfg diff --git a/build/Makefile.gcov b/build/Makefile.gcov index 13985a93a101..5097bfaaa277 100644 --- a/build/Makefile.gcov +++ b/build/Makefile.gcov @@ -16,23 +16,6 @@ LCOV_EXCLUDES = \ '$(top_srcdir)/parse_date.re' \ '$(top_srcdir)/parse_iso_intervals.re' -GCOVR_EXCLUDES = \ - 'ext/bcmath/libbcmath/.*' \ - 'ext/date/lib/.*' \ - 'ext/fileinfo/libmagic/.*' \ - 'ext/gd/libgd/.*' \ - 'ext/hash/sha3/.*' \ - 'ext/lexbor/lexbor/.*' \ - 'ext/mbstring/libmbfl/.*' \ - 'ext/opcache/jit/ir/.*' \ - 'ext/pcre/pcre2lib/.*' \ - 'ext/uri/uriparser/.*' - -# These patterns have implicit ^/$ anchors. -GCOVR_EXCLUDE_LINES_BY_PATTERNS = \ - '.*\b(ZEND_PARSE_PARAMETERS_(START|END|NONE)|Z_PARAM_).*' \ - '\s*(default:\s*)?ZEND_UNREACHABLE\(\);\s*' - lcov: lcov-html php_lcov.info: @@ -56,15 +39,11 @@ gcovr-html: @echo "Generating gcovr HTML" @rm -rf gcovr_html/ @mkdir gcovr_html - gcovr -sr . -o gcovr_html/index.html --html --html-details --exclude-unreachable-branches --exclude-throw-branches \ - $(foreach pattern, $(GCOVR_EXCLUDE_LINES_BY_PATTERNS), --exclude-lines-by-pattern $(pattern)) \ - $(foreach lib, $(GCOVR_EXCLUDES), -e $(lib)) + gcovr -r . -o gcovr_html/index.html --html --html-details gcovr-xml: @echo "Generating gcovr XML" @rm -f gcovr.xml - gcovr -sr . -o gcovr.xml --xml --exclude-unreachable-branches --exclude-throw-branches \ - $(foreach pattern, $(GCOVR_EXCLUDE_LINES_BY_PATTERNS), --exclude-lines-by-pattern $(pattern)) \ - $(foreach lib, $(GCOVR_EXCLUDES), -e $(lib)) + gcovr -r . -o gcovr.xml --xml .PHONY: gcovr-html lcov-html php_lcov.info diff --git a/gcovr.cfg b/gcovr.cfg new file mode 100644 index 000000000000..a8267cd6e000 --- /dev/null +++ b/gcovr.cfg @@ -0,0 +1,19 @@ +print-summary = yes + +exclude-throw-branches = yes +exclude-unreachable-branches = yes + +exclude = ext/bcmath/libbcmath/.* +exclude = ext/date/lib/.* +exclude = ext/fileinfo/libmagic/.* +exclude = ext/gd/libgd/.* +exclude = ext/hash/sha3/.* +exclude = ext/lexbor/lexbor/.* +exclude = ext/mbstring/libmbfl/.* +exclude = ext/opcache/jit/ir/.* +exclude = ext/pcre/pcre2lib/.* +exclude = ext/uri/uriparser/.* + +# These patterns have implicit ^/$ anchors. +exclude-lines-by-pattern = .*\b(ZEND_PARSE_PARAMETERS_(START|END|NONE)|Z_PARAM_).* +exclude-lines-by-pattern = \s*(default:\s*)?ZEND_UNREACHABLE\(\);\s* From 0c6fc66848a9810fdbef3749cb4b3ed1d79685fd Mon Sep 17 00:00:00 2001 From: Shivam Mathur Date: Tue, 7 Apr 2026 12:34:21 +0530 Subject: [PATCH 4/5] curl: add support for brotli and zstd on Windows Fixes GH-21599 Fixes winlibs/cURL#26 Closes GH-21662 --- NEWS | 2 ++ ext/curl/config.w32 | 5 ++++- ext/curl/tests/check_win_config.phpt | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 21a709ab4212..aa91603d8723 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.2.31 +- Curl: + . Add support for brotli and zstd on Windows. (Shivam Mathur) 18 Dec 2025, PHP 8.2.30 diff --git a/ext/curl/config.w32 b/ext/curl/config.w32 index f722c5faca5e..eda7604bc118 100644 --- a/ext/curl/config.w32 +++ b/ext/curl/config.w32 @@ -24,7 +24,10 @@ if (PHP_CURL != "no") { (ver_num <= parseInt("0x073b00") || ver_num > parseInt("0x073b00") && CHECK_LIB("normaliz.lib", "curl", PHP_CURL) && CHECK_LIB("libssh2.lib", "curl", PHP_CURL) && - CHECK_LIB("nghttp2.lib", "curl", PHP_CURL)) + CHECK_LIB("nghttp2.lib", "curl", PHP_CURL) && + CHECK_LIB("brotlidec.lib", "curl", PHP_CURL) && + CHECK_LIB("brotlicommon.lib", "curl", PHP_CURL) && + CHECK_LIB("libzstd.lib", "curl", PHP_CURL)) ) { EXTENSION("curl", "interface.c multi.c share.c curl_file.c"); AC_DEFINE('HAVE_CURL', 1, 'Have cURL library'); diff --git a/ext/curl/tests/check_win_config.phpt b/ext/curl/tests/check_win_config.phpt index fc29e3728197..56ebe36312ec 100644 --- a/ext/curl/tests/check_win_config.phpt +++ b/ext/curl/tests/check_win_config.phpt @@ -47,11 +47,11 @@ UNIX_SOCKETS => %r(Yes|No)%r PSL => No HTTPS_PROXY => Yes MULTI_SSL => %s -BROTLI => %s +BROTLI => Yes ALTSVC => Yes HTTP3 => No UNICODE => No -ZSTD => No +ZSTD => Yes HSTS => Yes GSASL => No Protocols => dict, file, ftp, ftps, gopher, %r(gophers, )?%rhttp, https, imap, imaps, ldap, ldaps, %r(mqtt, )?%rpop3, pop3s, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp%r(, ws)?(, wss)?%r From f05b1563babd74fb1e1ee48a8e413190df4b1b0a Mon Sep 17 00:00:00 2001 From: Weilin Du <108666168+LamentXU123@users.noreply.github.com> Date: Wed, 8 Apr 2026 02:33:51 +0800 Subject: [PATCH 5/5] [skip ci] Fix various typos in ext/xml{reader,writer} (GH-21660) --- ext/xmlreader/php_xmlreader.c | 2 +- ext/xmlreader/tests/expand.phpt | 2 +- ext/xmlwriter/php_xmlwriter.c | 2 +- ext/xmlwriter/tests/bug39504.phpt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index 27de3a290285..da337fd6dabb 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -755,7 +755,7 @@ PHP_METHOD(XMLReader, moveToAttributeNo) } /* }}} */ -/* {{{ Positions reader at attribute spcified by name and namespaceURI. +/* {{{ Positions reader at attribute specified by name and namespaceURI. Returns TRUE on success and FALSE on failure */ PHP_METHOD(XMLReader, moveToAttributeNs) { diff --git a/ext/xmlreader/tests/expand.phpt b/ext/xmlreader/tests/expand.phpt index 9d4545d16897..5244121f6502 100644 --- a/ext/xmlreader/tests/expand.phpt +++ b/ext/xmlreader/tests/expand.phpt @@ -1,5 +1,5 @@ --TEST-- -XMLReader: Expand into existing DOM documet +XMLReader: Expand into existing DOM document --EXTENSIONS-- xmlreader dom diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c index 0c65305c6827..8d343aadf263 100644 --- a/ext/xmlwriter/php_xmlwriter.c +++ b/ext/xmlwriter/php_xmlwriter.c @@ -432,7 +432,7 @@ PHP_FUNCTION(xmlwriter_write_element) } /* }}} */ -/* {{{ Write full namesapced element tag - returns FALSE on error */ +/* {{{ Write full namespaced element tag - returns FALSE on error */ PHP_FUNCTION(xmlwriter_write_element_ns) { xmlTextWriterPtr ptr; diff --git a/ext/xmlwriter/tests/bug39504.phpt b/ext/xmlwriter/tests/bug39504.phpt index 0cb509d37dd5..eafcd375da93 100644 --- a/ext/xmlwriter/tests/bug39504.phpt +++ b/ext/xmlwriter/tests/bug39504.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #39504 (xmlwriter_write_dtd_entity() creates Attlist tag, not enity) +Bug #39504 (xmlwriter_write_dtd_entity() creates Attlist tag, not entity) --EXTENSIONS-- xmlwriter --FILE--