Commit 2cd16757b2f for php.net

commit 2cd16757b2f9aba35e5fb5c1de67873082d53f17
Merge: a1a7bd4b8b1 f9e04180aef
Author: Jakub Zelenka <bukka@php.net>
Date:   Tue Sep 22 11:03:08 2026 +0200

    Merge branch 'PHP-8.3' into PHP-8.4

    * PHP-8.3:
      ext/soap: make GHSA-cj93-vc83-wgqv test lean and reliable
      Add NEWS entries
      ext/standard: Fix 1-char relative Location redirects after GH-23467
      [http] Fix out-of-bounds read on empty Location header
      Fix GHSA-ch8v-r6jh-4vvr: encode 0xFF in FILTER_SANITIZE_ENCODED
      Fix GHSA-9f67-6fw4-hpfp
      Fix GHSA-j3wh-g957-2m85: phar tar entry injection
      Fix GHSA-cj93-vc83-wgqv
      Fix GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap XML parsing and decoding
      Fix GHSA-fpwc-w8rq-cr92: strip credentials from user headers on cross-origin redirects
      Fix GHSA-r6x9-5r99-36j7: Various packet overreads in mysqlnd wireprotocol
      Fix GHSA-xr7j-rvgx-xq5p: OOB read in php_openssl_matches_wildcard_name()
      Fix GHSA-vvx9-73fr-5jjx: do not fall back to CN if the cert has a service ID
      Fix GHSA-62xp-839h-2637: FastCGI allowed_clients compared only 96 bits of IPv6 addresses
      Fix heap-buffer-overflow in convert stream filters with NUL in line-break-chars

    # Conflicts:
    #       ext/openssl/xp_ssl.c

diff --cc NEWS
index 3587344ca1b,0ba2c03f817..a37bfa30e4b
--- a/NEWS
+++ b/NEWS
@@@ -1,249 -1,51 +1,277 @@@
  PHP                                                                        NEWS
  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 -?? ??? ????, PHP 8.3.34
 +?? ??? ????, PHP 8.4.27

 -- Filter:
 -  . Fixed GHSA-ch8v-r6jh-4vvr (FILTER_SANITIZE_ENCODED does not encode 0xFF).
 +- CLI
 +  . Fix GH-22567 (Windows ZTS CLI SAPI should refresh its TSRMLS cache during
 +    request activation). (matyhtf)
 +
 +- Core
 +  . Fix GH-21999: GC inconsistency with lazy object, var_dump(), and object
 +    comparison. (Arnaud)
 +
 +- DOM:
 +  . Fixed use-after-free when re-constructing a DOMXPath whose php:function
 +    registrations are freed while still reachable from the cycle collector.
 +    (Ilia Alshanetsky)
 +  . Fixed bug GH-23365 (DOMNode::insertBefore($n, $n) drops the node and
 +    leaves a self-referencing sibling list). (David Carlier)
 +  . Fixed Dom\HTMLDocument::getElementById() not finding ids of SVG and
 +    MathML elements. (Ilia Alshanetsky)
 +  . Fixed Dom\HTMLDocument giving attributes the namespace of their element
 +    when a fragment is parsed with an xlink, xml or xmlns context element.
 +    (Ilia Alshanetsky)
 +  . Fixed bug GH-23729 (DOMXPath::__construct() use-after-free during an
 +    evaluation). (David Carlier)
 +
 +- FTP:
 +  . Fixed bug GH-23619 (cryptic error on servers that don't support TLS
 +    session resumption on data connection). (ndossche)
 +
 +- Intl:
 +  . Fixed cloning IntlDateFormatter and MessageFormatter losing PHP-side state
 +    such as dateType, timeType, calendar and the message pattern.
 +    (Ilia Alshanetsky)
 +
 +- Lexbor:
 +  . Merge patches lexbor/lexbor@8a14bc0 and lexbor/lexbor@f67ce4b, fixing a
 +    heap buffer overflow in :lexbor-contains() parsing and buffer overflows
 +    in malformed decode replay. (alexandre-daubois)
 +
 +- MBString:
 +  . Fixed bug GH-23106 (mb_strpos() reads past the end of a haystack ending in
 +    a truncated UTF-8 sequence). (Lazizbek Ergashev)
 +
 +- MySQLi:
 +  . Fix GH-22854: Fixed failed assertion when accessing mysqli property after
 +    failed reconnection. (Kamil Tekiela)
 +
 +- Opcache:
 +  . Fixed OSS-Fuzz #546798343 (Heap-buffer-overflow in optimizer with
 +    FCCs and inlining). (ndossche)
 +  . Fixed bug GH-23693 (Tracing JIT produces wrong results for a guard on a
 +    loop-invariant addition). (Ilia Alshanetsky)
 +  . Fixed OSS-Fuzz #5674034779193344 (Read of uninitialized memory in
 +    is_cacheable_stream_path()). (ndossche)
 +
 +- PDO:
 +  . Fixed PDOStatement::getColumnMeta() reading out of bounds for an invalid
 +    column index. (Ilia Alshanetsky)
 +  . Fixed PDOStatement::bindColumn() registering a binding for a column name
 +    that is not in the result set. (Ilia Alshanetsky)
 +
 +- Readline:
 +  . Fixed a heap over-read in the interactive shell prompt when cli.prompt is
 +    set to an empty string. (Ilia Alshanetsky)
 +
 +- Sockets:
 +  . Fixed socket_select() silently truncating sets larger than FD_SETSIZE on
 +    Windows. (David Carlier)
 +
 +- SQLite:
 +  . Fixed a crash when SQLite3::close() is called from a userland callback.
      (Ilia Alshanetsky)

 +- Standard:
 +  . Fixed three Windows-only proc_open() defects: an uninitialized
 +    PROCESS_INFORMATION, an indeterminate comspec pointer after a failed
 +    lookup, and an unchecked CreateFileA() failure. (Ilia Alshanetsky)
 +
 +- XSL:
 +  . Fixed bug GH-23730 (use-after-free when XSLTProcessor::importStylesheet()
 +    is called during a transformation). (David Carlier)
 +
 +- Zip:
 +  . Fixed ZipArchive::extractTo() ignoring files given in a non-list array.
 +    (David Carlier)
 +  . Fixed bug GH-23747 (ZipArchive::close() use-after-free from a progress or
 +    cancel callback). (David Carlier)
 +
 +
 +24 Sep 2026, PHP 8.4.26
 +
 +- BCMath:
 +  . Fixed out-of-bounds read in bc_is_zero_for_scale() when scale exceeds
 +    n_scale. (Ilia Alshanetsky)
 +
 +- Core:
 +  . Fixed out-of-bounds reads during automatic UTF-16/32 encoding detection.
 +    (Yudai Takada)
 +  . Fixed bug GH-15375 (Nested "yield from" skips items after a valid() or
 +    next() call on the inner generator). (iliaal)
 +  . Fixed bug GH-23232 (lone namespace separator asks the autoloader for an
 +    empty class name). (spawnia)
 +  . Fixed bug GH-23301 (Nested "yield from" yields a value twice when the
 +    middle generator delegates again). (Lazizbek Ergashev)
 +
 +- CLI:
 +  . Fixed bug GH-23425 (sapi_cli_server_send_headers() does not check the
 +    return value of php_cli_server_client_send_through()). (Lazizbek Ergashev)
 +
 +- DOM:
 +  . Fixed NamedNodeMap::getNamedItemNS() with an empty URI not matching
 +    the null namespace in spec-following mode. (Ilia Alshanetsky)
 +  . Fixed a use-after-free when cloning a DOMNameSpaceNode after
 +    DOMDocument::xinclude(). (iliaal)
 +  . Fixed bug GH-23331 (UAF when node_list_unlink() skips attribute children
 +    that still have a live wrapper). (iliaal)
 +  . Fixed a use-after-free when Dom\Element::setAttributeNS() replaces the
 +    value of an attribute whose child still has a live wrapper. (iliaal)
 +
 +- GD:
 +  . Fixed imageaffinematrixget() and imageaffinematrixconcat() reporting the
 +    wrong argument in error messages. (Weilin Du)
 +  . Fixed bug GH-23457 (imagebmp() is extremely slow when writing to a file).
 +    (Lazizbek Ergashev)
 +
  - FPM:
 +  . Fixed bug GH-19320 (FPM UID and GID overflow). (Pratik Bhujel)
+   . Fixed GHSA-62xp-839h-2637 (IPv6 ACL bypass in FastCGI listen.allowed_clients
+     due to partial address comparison). (CVE-2026-91768) (Alexandre Daubois)

 +- Hash:
 +  . Fixed a buffer overflow in hash_pbkdf2() with a large output length.
 +    (Lazizbek Ergashev)
 +
 +- Intl:
 +  . Fixed grapheme_strpos() and grapheme_strrpos() with an empty needle
 +    returning UTF-16 offsets instead of grapheme offsets. (Ilia Alshanetsky)
 +  . Fixed a memory leak when dumping IntlCalendar instances. (Ilia Alshanetsky)
 +  . Fixed a memory leak when iterating IntlBreakIterator::getPartsIterator()
 +    results. (iliaal)
 +  . Fixed a double-free when IntlGregorianCalendar construction fails after
 +    the ICU constructor adopts the TimeZone. (iliaal)
 +  . Fixed bug GH-23094 (NumberFormatter parsing offsets use UTF-16 positions
 +    for UTF-8 strings). (ColumbusLabs)
 +  . Fixed Locale::parseLocale() reading past a trailing '-' or '_'.
 +    (iliaal, Xuyang Zhang)
 +  . Fixed grapheme_str_split() treating UBRK_DONE as a byte index. (iliaal)
 +  . Fixed a leak in Locale::getKeywords() when a keyword value cannot be
 +    read. (iliaal)
 +  . Fixed a use-after-free when IntlRuleBasedBreakIterator is constructed
 +    from compiled rules. (iliaal)
 +
 +- MBString:
 +  . Fixed mb_ereg_replace() emitting a NUL or out-of-bounds bytes in the
 +    replacement when a \k<name> backref has no closing delimiter.
 +    (Ilia Alshanetsky)
 +
+ - MySQLnd:
+   . Fixed GHSA-r6x9-5r99-36j7 (Various packet overreads in mysqlnd wire
+     protocol). (CVE-2025-1218) (Jakub Zelenka, Nora Dossche)
+
 +- ODBC:
 +  . Fixed odbc_field_len(), odbc_field_scale() and odbc_field_type()
 +    returning uninitialized memory when SQLColAttribute fails.
 +    (Ilia Alshanetsky)
 +
 +- Opcache:
 +  . Fixed a crash when the huge page SHM remap discarded mappings outside the
 +    reserved address range. (Piotr Hałas)
 +  . Fixed opcache.protect_memory race under ZTS. (realFlowControl)
 +  . Fixed bug GH-23288 (Crash on restart when opcache.interned_strings_buffer
 +    is overridden in an individual FPM pool). (David Carlier)
 +  . Fixed a tracing JIT crash when compiling a side trace for a method of a
 +    class that could not be stored in the inheritance cache. (GH-21710)
 +    (Arnaud, iliaal)
 +
+ - OpenSSL:
+   . Fixed GHSA-vvx9-73fr-5jjx (TLS hostname verification falls back to CN after
+     SAN mismatch). (CVE-2026-91769) (Jakub Zelenka)
+   . Fixed GHSA-xr7j-rvgx-xq5p (Heap buffer overflow in
+     php_openssl_matches_wildcard_name() on crafted server certificate wildcard
+     CN). (CVE-2026-91767) (Jakub Zelenka)
+
 +- PDO:
 +  . Fixed a leak when a persistent connection failed a liveness check
 +    with no other live PDO handle. (iliaal)
 +
 +- PDO_ODBC:
 +  . Fixed bug GH-23444 (ODBC_ATTR_ASSUME_UTF8 corrupts Unicode data outside
 +    Windows). (Calvin Buckley, Lazizbek Ergashev)
 +
 +- PDO_PGSQL:
 +  . Fixed PDO::CURSOR_SCROLL statements closing a cursor that does not exist.
 +    (KentarouTakeda)
 +
 +- PDO Sqlite:
 +  . Fixed bug GH-20214 (PDO::FETCH_DEFAULT unexpected behavior with
 +    PDOStatement::setFetchMode). (SakiTakamachi)
 +
  - Phar:
 +  . Fixed bug GH-23418 (Use-after-free when looking up mounted directories).
 +    (Weilin Du)
 +  . Fixed bug GH-23477 (Memory leak on duplicate native Phar manifest entries).
 +    (Weilin Du)
+   . Fixed GHSA-j3wh-g957-2m85 (Integer overflow in phar_tar_number() allowing
+     TAR archive entry injection). (CVE-2026-6103) (Jakub Zelenka)

 +- SNMP:
 +  . Fixed bug GH-23453 (SNMP::setSecurity() frees a non-malloced address with a
 +    context engine ID longer than 32 bytes). (Lazizbek Ergashev)
 +
  - SOAP:
 +  . Fixed bug GH-23447 (Segfault when a class passed to SoapServer::setClass()
 +    fails to initialize). (Lazizbek Ergashev)
 +  . Fixed WSDL cache corruption when a soap:header defines headerfaults.
 +    (Ilia Alshanetsky)
 +  . Fixed stack overflow when parsing a WSDL with self-referential schema
 +    groups or attributeGroups. (Ilia Alshanetsky)
+   . Fixed GHSA-rgrp-mwpx-f6rm (Unbounded recursion in server-side
+     cleanup_xml_node()). (CVE-2026-91765) (Alexandre Daubois)
+   . Fixed GHSA-cj93-vc83-wgqv (Integer overflow to buffer overflow in SOAP HTTP
+     parsing). (CVE-2025-14181) (Nora Dossche, Jakub Zelenka)

  - Standard:
 +  . Fixed a segfault when a stream filter callback unsets StreamBucket::$data
 +    before re-attaching the bucket. (iliaal)
-   . Fixed an out-of-bounds read when following a redirect response with an
-     empty Location header. (iliaal)
++  . Fixed GHSA-7875-c8px-7q5f (Out-of-bounds read in the HTTP stream wrapper
++    when following a redirect with an empty Location header). (CVE-2026-93682)
++    (Ilia Alshanetsky, Jordi Kroon)
 +  . Fixed a memory leak in array_merge_recursive() when the recursive merge of
 +    an object converted to an array fails. (David Carlier)
 +  . Fixed read buffer compaction in php_stream_filter_flush(). (crystarm)
 +  . Fixed bug GH-22410 (Incorrect float behavior with large numbers).
 +    (arshidkv12)
 +  . Fixed GH-23338 (fsockopen()/pfsockopen() ValueError reported wrong
 +    argument number for $timeout). (lacatoire)
 +  . Fixed bug GH-23576 (Next index for array returned from array_keys() is
 +    wrong). (Lazizbek Ergashev)
+   . Fixed GHSA-88hq-2827-7pg6 (Out-of-bounds read in convert.* stream filters
+     when line-break-chars contains NUL). (CVE-2026-92842) (geeknik)
+   . Fixed GHSA-fpwc-w8rq-cr92 (Cross-origin credential leak in HTTP stream
+     wrapper redirects). (CVE-2026-91766) (Alexandre Daubois, Jakub Zelenka)
 -  . Fixed GHSA-7875-c8px-7q5f (Out-of-bounds read in the HTTP stream wrapper
 -    when following a redirect with an empty Location header). (CVE-2026-93682)
 -    (Ilia Alshanetsky, Jordi Kroon)
 +
 +- SimpleXML:
 +  . Fixed writing to a dimension of the object returned by attributes() not
 +    creating the attribute. (Ilia Alshanetsky)
 +  . Fixed child elements of the element returned by
 +    SimpleXMLElement::addChild() not being accessible by property name when
 +    namespaces are involved. (Ilia Alshanetsky)

+ - Windows:
+   . Fixed GHSA-9f67-6fw4-hpfp (Reserved device names are not rejected before
+     file and stream I/O). (CVE-2026-17545) (Shivam Mathur, Jakub Zelenka)
+
 +- Zip:
 +  . Fixed bug GH-23276 (ZipArchive subclass storing its own stream cannot be
 +    garbage collected). (Weilin Du, ndossche)
 +  . Fixed ZipArchive::extractTo() and ZipArchive::getFrom*() reporting success
 +    on corrupted entries. (David Carlier)
 +  . Fixed ZipArchive::getNameIndex() truncating the entry index to int.
 +    (David Carlier)
 +  . Fixed fstat() on a zip:// stream reporting success when the archive cannot
 +    be opened. (David Carlier)
 +
 +- SAPI:
 +  . Fixed fuzzer targets failing to build in isolation. (Mrmaxmeier)
 +  . Fixed returns uninitialized value on LiteSpeed lsapi SAPI (Go Kudo)
 +
 +27 Aug 2026, PHP 8.4.25

 -30 Jul 2026, PHP 8.3.33
 +- Core:
 +  . Fixed bug GH-23088 (Stack overflow when comparing deeply nested arrays).
 +    (Lazizbek Ergashev)

  - Date:
    . Fixed leak on double DatePeriod::__construct() call. (ilutov)
diff --cc ext/openssl/xp_ssl.c
index 56d372c6fe0,ae6abf24c3f..ae12c8eb612
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@@ -413,9 -417,8 +413,8 @@@ static bool php_openssl_x509_fingerprin

  static bool php_openssl_matches_wildcard_name(const char *subjectname, const char *certname) /* {{{ */
  {
 -	char *wildcard = NULL;
 +	const char *wildcard = NULL;
- 	ptrdiff_t prefix_len;
- 	size_t suffix_len, subject_len;
+ 	size_t prefix_len, suffix_len, subject_len;

  	if (strcasecmp(subjectname, certname) == 0) {
  		return 1;
@@@ -472,10 -478,9 +474,12 @@@ static bool php_openssl_matches_san_lis
  		GENERAL_NAME *san = sk_GENERAL_NAME_value(alt_names, i);

  		if (san->type == GEN_DNS) {
+ 			*has_service_id = true;
+
 -			ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName);
 +			if (ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName) < 0) {
 +				/* TODO: warn ? */
 +				continue;
 +			}
  			if ((size_t)ASN1_STRING_length(san->d.dNSName) != strlen((const char*)cert_name)) {
  				OPENSSL_free(cert_name);
  				/* prevent null-byte poisoning*/
diff --cc ext/soap/php_http.c
index 125c9258200,27bea0c56d2..7a75523f0b9
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@@ -1452,10 -1434,11 +1452,11 @@@ static zend_string* get_http_body(php_s
  {
  	zend_string *http_buf = NULL;
  	char *header;
- 	int header_close = close, header_chunked = 0, header_length = 0, http_buf_size = 0;
+ 	int header_close = close, header_chunked = 0, header_length = 0;
+ 	size_t http_buf_size = 0;

  	if (!close) {
 -		header = get_http_header_value(headers, "Connection: ");
 +		header = get_http_header_value(headers, "Connection:");
  		if (header) {
  			if(!strncasecmp(header, "close", sizeof("close")-1)) header_close = 1;
  			efree(header);
diff --cc ext/soap/php_xml.c
index d39688b59b5,340dbd8ea4a..d353dc90a9d
--- a/ext/soap/php_xml.c
+++ b/ext/soap/php_xml.c
@@@ -32,25 -32,23 +32,23 @@@ static bool is_blank(const xmlChar* str
  		}
  		str++;
  	}
 -	return 1;
 +	return true;
  }

- /* removes all empty text, comments and other insignoficant nodes */
+ /* removes all empty text, comments and other insignoficant nodes.
+  * Iterative because recursion overflows the stack on a deep document. */
  static void cleanup_xml_node(xmlNodePtr node)
  {
- 	xmlNodePtr trav;
- 	xmlNodePtr del = NULL;
+ 	xmlNodePtr parent = node;
+ 	xmlNodePtr trav = node->children;

- 	trav = node->children;
  	while (trav != NULL) {
- 		if (del != NULL) {
- 			xmlUnlinkNode(del);
- 			xmlFreeNode(del);
- 			del = NULL;
- 		}
+ 		xmlNodePtr next = trav->next;
+
  		if (trav->type == XML_TEXT_NODE) {
  			if (is_blank(trav->content)) {
- 				del = trav;
+ 				xmlUnlinkNode(trav);
+ 				xmlFreeNode(trav);
  			}
  		} else if ((trav->type != XML_ELEMENT_NODE) &&
  		           (trav->type != XML_CDATA_SECTION_NODE)) {