diff '--color=auto' -Naur a/.github/CODEOWNERS b/.github/CODEOWNERS
--- a/.github/CODEOWNERS	2025-10-21 19:23:55.000000000 +0000
+++ b/.github/CODEOWNERS	2025-11-18 21:43:27.120565309 +0000
@@ -16,18 +16,18 @@
 
 /.github @TimWolla
 /build/gen_stub.php @kocsismate
-/ext/bcmath @Girgias @nielsdos @SakiTakamachi
+/ext/bcmath @Girgias @ndossche @SakiTakamachi
 /ext/curl @adoy
 /ext/date @derickr
 /ext/dba @Girgias
-/ext/dom @nielsdos
+/ext/dom @ndossche
 /ext/ffi @dstogov
 /ext/gd @devnexen
 /ext/gettext @devnexen
 /ext/gmp @Girgias
 /ext/intl @devnexen
 /ext/json @bukka
-/ext/libxml @nielsdos
+/ext/libxml @ndossche
 /ext/mbstring @alexdowad @youkidearitai
 /ext/mysqli @bukka @kamil-tekiela
 /ext/mysqlnd @bukka @kamil-tekiela @SakiTakamachi
@@ -46,15 +46,16 @@
 /ext/random @TimWolla @zeriyoshi
 /ext/reflection @DanielEScherzer
 /ext/session @Girgias
-/ext/simplexml @nielsdos
-/ext/soap @nielsdos
+/ext/simplexml @ndossche
+/ext/soap @ndossche
 /ext/sockets @devnexen
 /ext/spl @Girgias
 /ext/standard @bukka
-/ext/xml @nielsdos
-/ext/xmlreader @nielsdos
-/ext/xmlwriter @nielsdos
-/ext/xsl @nielsdos
+/ext/tidy @ndossche
+/ext/xml @ndossche
+/ext/xmlreader @ndossche
+/ext/xmlwriter @ndossche
+/ext/xsl @ndossche
 /main @bukka
 /sapi/fpm @bukka
 /Zend/Optimizer @dstogov
diff '--color=auto' -Naur a/.github/actions/notify-slack/action.yml b/.github/actions/notify-slack/action.yml
--- a/.github/actions/notify-slack/action.yml	2025-10-21 19:23:55.000000000 +0000
+++ b/.github/actions/notify-slack/action.yml	1970-01-01 00:00:00.000000000 +0000
@@ -1,10 +0,0 @@
-name: Notify Slack
-inputs:
-  token:
-    required: true
-runs:
-  using: composite
-  steps:
-    - shell: bash
-      run: >-
-        curl -X POST -H 'Content-type: application/json' --data '{"attachments": [{"text": "Job in *nightly* failed", "footer": "<https://github.com/php/php-src/actions/runs/${{ github.run_id }}|View Run>", "color": "danger", "mrkdwn_in": ["text"]}]}' ${{ inputs.token }}
diff '--color=auto' -Naur a/.github/nightly_matrix.php b/.github/nightly_matrix.php
--- a/.github/nightly_matrix.php	2025-10-21 19:23:55.000000000 +0000
+++ b/.github/nightly_matrix.php	2025-11-18 21:43:27.122170109 +0000
@@ -49,8 +49,8 @@
 
 $trigger = $argv[1] ?? 'schedule';
 $attempt = (int) ($argv[2] ?? 1);
-$monday = date('w', time()) === '1';
-$discard_cache = $monday
+$sunday = date('w', time()) === '0';
+$discard_cache = $sunday
     || ($trigger === 'schedule' && $attempt !== 1)
     || $trigger === 'workflow_dispatch';
 if ($discard_cache) {
diff '--color=auto' -Naur a/.github/scripts/windows/test_task.bat b/.github/scripts/windows/test_task.bat
--- a/.github/scripts/windows/test_task.bat	2025-10-21 19:23:55.000000000 +0000
+++ b/.github/scripts/windows/test_task.bat	2025-11-18 21:43:27.122289494 +0000
@@ -36,8 +36,7 @@
 rem setup PostgreSQL related exts
 set PGUSER=postgres
 set PGPASSWORD=Password12!
-rem set PGSQL_TEST_CONNSTR=host=127.0.0.1 dbname=test port=5432 user=postgres password=Password12!
-echo ^<?php $conn_str = "host=127.0.0.1 dbname=test port=5432 user=%PGUSER% password=%PGPASSWORD%"; ?^> >> "./ext/pgsql/tests/config.inc"
+set PGSQL_TEST_CONNSTR=host=127.0.0.1 dbname=test port=5432 user=%PGUSER% password=%PGPASSWORD%
 set PDO_PGSQL_TEST_DSN=pgsql:host=127.0.0.1 port=5432 dbname=test user=%PGUSER% password=%PGPASSWORD%
 set TMP_POSTGRESQL_BIN=%PGBIN%
 "%TMP_POSTGRESQL_BIN%\createdb.exe" test
diff '--color=auto' -Naur a/.github/workflows/nightly-results.yml b/.github/workflows/nightly-results.yml
--- a/.github/workflows/nightly-results.yml	1970-01-01 00:00:00.000000000 +0000
+++ b/.github/workflows/nightly-results.yml	2025-11-18 21:43:27.122539697 +0000
@@ -0,0 +1,16 @@
+name: Nightly results
+on:
+  workflow_run:
+    workflows:
+      - Nightly
+    types:
+      - completed
+jobs:
+  on-failure:
+    runs-on: ubuntu-latest
+    if: ${{ github.repository == 'php/php-src' && github.event.workflow_run.conclusion == 'failure' }}
+    steps:
+      - run: |
+          export DEBIAN_FRONTEND=noninteractive
+          sudo apt-get install -y curl
+          curl -X POST -H 'Content-type: application/json' --data '{"attachments": [{"text": "Job(s) in *nightly* failed", "footer": "<${{ github.event.workflow_run.html_url }}|View Run>", "color": "danger", "mrkdwn_in": ["text"]}]}' ${{ secrets.ACTION_MONITORING_SLACK }}
diff '--color=auto' -Naur a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
--- a/.github/workflows/nightly.yml	2025-10-21 19:23:55.000000000 +0000
+++ b/.github/workflows/nightly.yml	2025-11-18 21:43:27.122644715 +0000
@@ -136,12 +136,6 @@
             -d opcache.enable_cli=1
       - name: Extra tests
         uses: ./.github/actions/extra-tests
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
-
   LINUX_X64:
     services:
       mysql:
@@ -273,11 +267,6 @@
         uses: ./.github/actions/extra-tests
       - name: Verify generated files are up to date
         uses: ./.github/actions/verify-generated-files
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
   LINUX_X32:
     strategy:
       fail-fast: false
@@ -362,11 +351,6 @@
             -d opcache.enable_cli=1
       - name: Extra tests
         uses: ./.github/actions/extra-tests
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
   MACOS:
     strategy:
       fail-fast: false
@@ -425,11 +409,6 @@
         uses: ./.github/actions/extra-tests
       - name: Verify generated files are up to date
         uses: ./.github/actions/verify-generated-files
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
   COVERAGE_DEBUG_NTS:
     if: inputs.branch == 'master'
     services:
@@ -491,11 +470,6 @@
           fail_ci_if_error: true
           token: ${{ secrets.CODECOV_TOKEN }}
           verbose: true
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
   COMMUNITY:
     strategy:
       fail-fast: false
@@ -683,11 +657,6 @@
           if [ $EXIT_CODE -gt 128 ]; then
             exit 1
           fi
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
   OPCACHE_VARIATION:
     services:
       mysql:
@@ -774,11 +743,6 @@
             -d opcache.file_cache_only=1
       - name: Verify generated files are up to date
         uses: ./.github/actions/verify-generated-files
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
   MSAN:
     name: MSAN
     runs-on: ubuntu-${{ inputs.ubuntu_version }}
@@ -866,11 +830,6 @@
             -d opcache.enable_cli=1
       - name: Verify generated files are up to date
         uses: ./.github/actions/verify-generated-files
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
   LIBMYSQLCLIENT:
     name: LIBMYSQLCLIENT
     runs-on: ubuntu-${{ inputs.ubuntu_version }}
@@ -913,11 +872,6 @@
           withMysqli: ${{ inputs.libmysqlclient_with_mysqli }}
       - name: Verify generated files are up to date
         uses: ./.github/actions/verify-generated-files
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
   PECL:
     if: inputs.branch == 'master'
     runs-on: ubuntu-22.04
@@ -1025,11 +979,6 @@
           /opt/php/bin/phpize
           ./configure --prefix=/opt/php --with-php-config=/opt/php/bin/php-config
           make -j$(/usr/bin/nproc)
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
   WINDOWS:
     strategy:
       fail-fast: false
diff '--color=auto' -Naur a/.github/workflows/root.yml b/.github/workflows/root.yml
--- a/.github/workflows/root.yml	2025-10-21 19:23:55.000000000 +0000
+++ b/.github/workflows/root.yml	2025-11-18 21:43:27.123249988 +0000
@@ -31,11 +31,6 @@
       - name: Generate Matrix
         id: set-matrix
         run: php .github/nightly_matrix.php "${{ github.event_name }}" "${{ github.run_attempt }}" "${{ github.head_ref || github.ref_name }}"
-      - name: Notify Slack
-        if: failure()
-        uses: ./.github/actions/notify-slack
-        with:
-          token: ${{ secrets.ACTION_MONITORING_SLACK }}
   NIGHTLY:
     needs: GENERATE_MATRIX
     name: ${{ matrix.branch.ref }}
diff '--color=auto' -Naur a/EXTENSIONS b/EXTENSIONS
--- a/EXTENSIONS	2025-10-21 19:23:55.000000000 +0000
+++ b/EXTENSIONS	2025-11-18 21:43:27.123406543 +0000
@@ -486,6 +486,7 @@
 PRIMARY MAINTAINER:  John Coggeshall <john@php.net> (2003 - 2006)
                      Ilia Alshanetsky <iliaa@php.net> (2003 - 2009)
                      Nuno Lopes <nlopess@php.net> (2006 - 2012)
+                     Niels Dossche <nielsdos@php.net> (2025 - 2025)
 MAINTENANCE:         Maintained
 STATUS:              Working
 -------------------------------------------------------------------------------
diff '--color=auto' -Naur a/NEWS.orig b/NEWS.orig
--- a/NEWS.orig	1970-01-01 00:00:00.000000000 +0000
+++ b/NEWS.orig	2025-11-18 21:42:37.542923367 +0000
@@ -0,0 +1,1708 @@
+PHP                                                                        NEWS
+|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+21 Oct 2025, PHP 8.4.14
+
+- Core:
+  . Fixed bug GH-19765 (object_properties_load() bypasses readonly property
+    checks). (timwolla)
+  . Fixed hard_timeout with --enable-zend-max-execution-timers. (Appla)
+  . Fixed bug GH-19792 (SCCP causes UAF for return value if both warning and
+    exception are triggered). (nielsdos)
+  . Fixed bug GH-19653 (Closure named argument unpacking between temporary
+    closures can cause a crash). (nielsdos, Arnaud, Bob)
+  . Fixed bug GH-19839 (Incorrect HASH_FLAG_HAS_EMPTY_IND flag on userland
+    array). (ilutov)
+  . Fixed bug GH-19480 (error_log php.ini cannot be unset when open_basedir is
+    configured). (nielsdos)
+  . Fixed bug GH-20002 (Broken build on *BSD with MSAN). (outtersg)
+
+- CLI:
+  . Fix useless "Failed to poll event" error logs due to EAGAIN in CLI server
+    with PHP_CLI_SERVER_WORKERS. (leotaku)
+
+- Curl:
+  . Fix cloning of CURLOPT_POSTFIELDS when using the clone operator instead
+    of the curl_copy_handle() function to clone a CurlHandle. (timwolla)
+  . Fix curl build and test failures with version 8.16.
+    (nielsdos, ilutov, Jakub Zelenka)
+
+- Date:
+  . Fixed GH-17159: "P" format for ::createFromFormat swallows string literals.
+    (nielsdos)
+
+- DOM:
+  . Fix macro name clash on macOS. (Ruoyu Zhong)
+  . Fixed bug GH-20022 (docker-php-ext-install DOM failed). (nielsdos)
+
+- GD:
+  . Fixed GH-19955 (imagefttext() memory leak). (David Carlier)
+
+- MySQLnd:
+  . Fixed bug #67563 (mysqli compiled with mysqlnd does not take ipv6 adress
+    as parameter). (nielsdos)
+
+- Opcache:
+  . Fixed bug GH-19669 (assertion failure in zend_jit_trace_type_to_info_ex).
+    (Arnaud)
+  . Fixed bug GH-19831 (function JIT may not deref property value). (Arnaud)
+  . Fixed bug GH-19889 (race condition in zend_runtime_jit(),
+    zend_jit_hot_func()). (Arnaud)
+
+- Phar:
+  . Fix memory leak and invalid continuation after tar header writing fails.
+    (nielsdos)
+  . Fix memory leaks when creating temp file fails when applying zip signature.
+    (nielsdos)
+
+- SimpleXML:
+  . Fixed bug GH-19988 (zend_string_init with NULL pointer in simplexml (UB)).
+    (nielsdos)
+
+- Soap:
+  . Fixed bug GH-19784 (SoapServer memory leak). (nielsdos)
+  . Fixed bug GH-20011 (Array of SoapVar of unknown type causes crash).
+    (nielsdos)
+
+- Standard:
+  . Fixed bug GH-12265 (Cloning an object breaks serialization recursion).
+    (nielsdos)
+  . Fixed bug GH-19701 (Serialize/deserialize loses some data). (nielsdos)
+  . Fixed bug GH-19801 (leaks in var_dump() and debug_zval_dump()).
+    (alexandre-daubois)
+  . Fixed bug GH-20043 (array_unique assertion failure with RC1 array
+    causing an exception on sort). (nielsdos)
+  . Fixed bug GH-19926 (reset internal pointer earlier while splicing array
+    while COW violation flag is still set). (alexandre-daubois)
+  . Fixed bug GH-19570 (unable to fseek in /dev/zero and /dev/null).
+    (nielsdos, divinity76)
+
+- Streams:
+  . Fixed bug GH-19248 (Use strerror_r instead of strerror in main).
+    (Jakub Zelenka)
+  . Fixed bug GH-17345 (Bug #35916 was not completely fixed). (nielsdos)
+  . Fixed bug GH-19705 (segmentation when attempting to flush on non seekable
+    stream. (bukka/David Carlier)
+
+- XMLReader:
+  . Fixed bug GH-20009 (XMLReader leak on RelaxNG schema failure). (nielsdos)
+
+- Zip:
+  . Fixed bug GH-19688 (Remove pattern overflow in zip addGlob()). (nielsdos)
+  . Fixed bug GH-19932 (Memory leak in zip setEncryptionName()/setEncryptionIndex()).
+    (David Carlier)
+
+25 Sep 2025, PHP 8.4.13
+
+- Core:
+  . Fixed bug GH-18850 (Repeated inclusion of file with __halt_compiler()
+    triggers "Constant already defined" warning). (ilutov)
+  . Partially fixed bug GH-19542 (Scanning of string literals >=2GB will fail
+    due to signed int overflow). (ilutov)
+  . Fixed bug GH-19544 (GC treats ZEND_WEAKREF_TAG_MAP references as WeakMap
+    references). (Arnaud, timwolla)
+  . Fixed bug GH-19613 (Stale array iterator pointer). (ilutov)
+  . Fixed bug GH-19679 (zend_ssa_range_widening may fail to converge). (Arnaud)
+  . Fixed bug GH-19681 (PHP_EXPAND_PATH broken with bash 5.3.0). (Remi)
+  . Fixed bug GH-19720 (Assertion failure when error handler throws when
+    accessing a deprecated constant). (nielsdos)
+
+- CLI:
+  . Fixed bug GH-19461 (Improve error message on listening error with IPv6
+    address). (alexandre-daubois)
+
+- Date:
+  . Fixed date_sunrise() and date_sunset() with partial-hour UTC offset.
+    (ilutov)
+
+- DBA:
+  . Fixed bug GH-19706 (dba stream resource mismanagement). (nielsdos)
+
+- DOM:
+  . Fixed bug GH-19612 (Mitigate libxml2 tree dictionary bug). (nielsdos)
+
+- FPM:
+  . Fixed failed debug assertion when php_admin_value setting fails. (ilutov)
+
+- Intl:
+  . Fixed bug GH-11952 (Fix locale strings canonicalization for IntlDateFormatter
+    and NumberFormatter). (alexandre-daubois)
+
+- Opcache:
+  . Fixed bug GH-19493 (JIT variable not stored before YIELD). (Arnaud)
+
+- OpenSSL:
+  . Fixed bug GH-19245 (Success error message on TLS stream accept failure).
+    (Jakub Zelenka)
+
+- PGSQL:
+  . Fixed bug GH-19485 (potential use after free when using persistent pgsql
+    connections). (Mark Karpeles)
+
+- Phar:
+  . Fixed memory leaks when verifying OpenSSL signature. (Girgias)
+  . Fix memory leak in phar tar temporary file error handling code. (nielsdos)
+  . Fix metadata leak when phar convert logic fails. (nielsdos)
+  . Fix memory leak on failure in phar_convert_to_other(). (nielsdos)
+  . Fixed bug GH-19752 (Phar decompression with invalid extension
+    can cause UAF). (nielsdos)
+
+- Standard:
+  . Fixed bug GH-16649 (UAF during array_splice). (alexandre-daubois)
+  . Fixed bug GH-19577 (Avoid integer overflow when using a small offset
+    and PHP_INT_MAX with LimitIterator). (alexandre-daubois)
+
+- Streams:
+  . Remove incorrect call to zval_ptr_dtor() in user_wrapper_metadata().
+    (nielsdos)
+  . Fix OSS-Fuzz #385993744. (nielsdos)
+
+- Zip:
+  . Fix memory leak in zip when encountering empty glob result. (nielsdos)
+
+28 Aug 2025, PHP 8.4.12
+
+- Core:
+  . Fixed GH-19169 build issue with C++17 and ZEND_STATIC_ASSERT macro.
+    (psumbera)
+  . Fixed bug GH-19053 (Duplicate property slot with hooks and interface
+    property). (ilutov)
+  . Fixed bug GH-19044 (Protected properties are not scoped according to their
+    prototype). (Bob)
+  . Fixed bug GH-18581 (Coerce numeric string keys from iterators when argument
+    unpacking). (ilutov)
+  . Fixed OSS-Fuzz #434346548 (Failed assertion with throwing __toString in
+    binary const expr). (ilutov)
+  . Fixed bug GH-19305 (Operands may be being released during comparison).
+    (Arnaud)
+  . Fixed bug GH-19303 (Unpacking empty packed array into uninitialized array
+    causes assertion failure). (nielsdos)
+  . Fixed bug GH-19306 (Generator can be resumed while fetching next value from
+    delegated Generator). (Arnaud)
+  . Fixed bug GH-19326 (Calling Generator::throw() on a running generator with
+    a non-Generator delegate crashes). (Arnaud)
+  . Fixed bug GH-19280 (Stale array iterator position on rehashing). (ilutov)
+  . Fixed bug GH-18736 (Circumvented type check with return by ref + finally).
+    (ilutov)
+  . Fixed bug GH-19065 (Long match statement can segfault compiler during
+    recursive SSA renaming). (nielsdos, Arnaud)
+
+- Calendar:
+  . Fixed bug GH-19371 (integer overflow in calendar.c). (nielsdos)
+
+- FTP:
+  . Fix theoretical issues with hrtime() not being available. (nielsdos)
+
+- GD:
+  . Fix incorrect comparison with result of php_stream_can_cast(). (Girgias)
+
+- Hash:
+  . Fix crash on clone failure. (nielsdos)
+
+- Intl:
+  . Fix memleak on failure in collator_get_sort_key(). (nielsdos)
+  . Fix return value on failure for resourcebundle count handler. (Girgias)
+
+- LDAP:
+  . Fixed bug GH-18529 (additional inheriting of TLS int options).
+    (Jakub Zelenka)
+
+- LibXML:
+  . Fixed bug GH-19098 (libxml<2.13 segmentation fault caused by
+    php_libxml_node_free). (nielsdos)
+
+- MbString:
+  . Fixed bug GH-19397 (mb_list_encodings() can cause crashes on shutdown).
+    (nielsdos)
+
+- Opcache:
+  . Reset global pointers to prevent use-after-free in zend_jit_status().
+    (Florian Engelhardt)
+  . Fix issue with JIT restart and hooks. (nielsdos)
+  . Fix crash with dynamic function defs in hooks during preload. (nielsdos)
+
+- OpenSSL:
+  . Fixed bug GH-18986 (OpenSSL backend: incorrect RAND_{load,write}_file()
+    return value check). (nielsdos, botovq)
+  . Fix error return check of EVP_CIPHER_CTX_ctrl(). (nielsdos)
+  . Fixed bug GH-19428 (openssl_pkey_derive segfaults for DH derive with low
+    key_length param). (Jakub Zelenka)
+
+- PDO Pgsql:
+  . Fixed dangling pointer access on _pdo_pgsql_trim_message helper.
+    (dixyes)
+
+- SOAP:
+  . Fixed bug GH-18640 (heap-use-after-free ext/soap/php_encoding.c:299:32
+    in soap_check_zval_ref). (nielsdos)
+
+- Sockets:
+  . Fix some potential crashes on incorrect argument value. (nielsdos)
+
+- Standard:
+  . Fixed OSS Fuzz #433303828 (Leak in failed unserialize() with opcache).
+    (ilutov)
+  . Fix theoretical issues with hrtime() not being available. (nielsdos)
+  . Fixed bug GH-19300 (Nested array_multisort invocation with error breaks).
+    (nielsdos)
+
+- Windows:
+ . Free opened_path when opened_path_len >= MAXPATHLEN. (dixyes)
+
+31 Jul 2025, PHP 8.4.11
+
+- Calendar:
+  . Fixed jewishtojd overflow on year argument. (David Carlier)
+
+- Core:
+  . Fixed bug GH-18833 (Use after free with weakmaps dependent on destruction
+    order). (Daniil Gentili)
+  . Fixed bug GH-18907 (Leak when creating cycle in hook). (ilutov)
+  . Fix OSS-Fuzz #427814456. (nielsdos)
+  . Fix OSS-Fuzz #428983568 and #428760800. (nielsdos)
+
+- Curl:
+  . Fix memory leaks when returning refcounted value from curl callback.
+    (nielsdos)
+  . Remove incorrect string release. (nielsdos)
+
+- DOM:
+  . Fixed bug GH-18979 (Dom\XMLDocument::createComment() triggers undefined
+    behavior with null byte). (nielsdos)
+
+- LDAP:
+  . Fixed GH-18902 ldap_exop/ldap_exop_sync assert triggered on empty
+    request OID. (David Carlier)
+
+- MbString:
+  . Fixed bug GH-18901 (integer overflow mb_split). (nielsdos)
+
+- Opcache:
+  . Fixed bug GH-18639 (Internal class aliases can break preloading + JIT).
+    (nielsdos)
+  . Fixed bug GH-18899 (JIT function crash when emitting undefined variable
+    warning and opline is not set yet). (nielsdos)
+  . Fixed bug GH-14082 (Segmentation fault on unknown address 0x600000000018
+    in ext/opcache/jit/zend_jit.c). (nielsdos)
+  . Fixed bug GH-18898 (SEGV zend_jit_op_array_hot with property hooks
+    and preloading). (nielsdos)
+
+- OpenSSL:
+  . Fixed bug #80770 (It is not possible to get client peer certificate with
+    stream_socket_server). (Jakub Zelenka)
+
+- PCNTL:
+  . Fixed bug GH-18958 (Fatal error during shutdown after pcntl_rfork() or
+    pcntl_forkx() with zend-max-execution-timers). (Arnaud)
+
+- Phar:
+  . Fix stream double free in phar. (nielsdos, dixyes)
+  . Fix phar crash and file corruption with SplFileObject. (nielsdos)
+
+- SOAP:
+  . Fixed bug GH-18990, bug #81029, bug #47314 (SOAP HTTP socket not closing
+    on object destruction). (nielsdos)
+  . Fix memory leak when URL parsing fails in redirect. (Girgias)
+
+- SPL:
+  . Fixed bug GH-19094 (Attaching class with no Iterator implementation to
+    MultipleIterator causes crash). (nielsdos)
+
+- Standard:
+  . Fix misleading errors in printf(). (nielsdos)
+  . Fix RCN violations in array functions. (nielsdos)
+  . Fixed GH-18976 pack() overflow with h/H format and INT_MAX repeater value.
+    (David Carlier)
+
+- Streams:
+  . Fixed GH-13264 (fgets() and stream_get_line() do not return false on filter
+    fatal error). (Jakub Zelenka)
+
+- Zip:
+  . Fix leak when path is too long in ZipArchive::extractTo(). (nielsdos)
+
+03 Jul 2025, PHP 8.4.10
+
+- BcMath:
+  . Fixed bug GH-18641 (Accessing a BcMath\Number property by ref crashes).
+    (nielsdos)
+
+- Core:
+  . Fixed bugs GH-17711 and GH-18022 (Infinite recursion on deprecated attribute
+    evaluation) and GH-18464 (Recursion protection for deprecation constants not
+    released on bailout). (DanielEScherzer and ilutov)
+  . Fixed GH-18695 (zend_ast_export() - float number is not preserved).
+    (Oleg Efimov)
+  . Fix handling of references in zval_try_get_long(). (nielsdos)
+  . Do not delete main chunk in zend_gc. (danog, Arnaud)
+  . Fix compile issues with zend_alloc and some non-default options. (nielsdos)
+
+- Curl:
+  . Fix memory leak when setting a list via curl_setopt fails. (nielsdos)
+
+- Date:
+  . Fix leaks with multiple calls to DatePeriod iterator current(). (nielsdos)
+
+- DOM:
+  . Fixed bug GH-18744 (classList works not correctly if copy HTMLElement by
+    clone keyword). (nielsdos)
+
+- FPM:
+  . Fixed GH-18662 (fpm_get_status segfault). (txuna)
+
+- Hash:
+  . Fixed bug GH-14551 (PGO build fails with xxhash). (nielsdos)
+
+- Intl:
+  . Fix memory leak in intl_datetime_decompose() on failure. (nielsdos)
+  . Fix memory leak in locale lookup on failure. (nielsdos)
+
+- Opcache:
+  . Fixed bug GH-18743 (Incompatibility in Inline TLS Assembly on Alpine 3.22).
+    (nielsdos, Arnaud)
+
+- ODBC:
+  . Fix memory leak on php_odbc_fetch_hash() failure. (nielsdos)
+
+- OpenSSL:
+  . Fix memory leak of X509_STORE in php_openssl_setup_verify() on failure.
+    (nielsdos)
+  . Fixed bug #74796 (Requests through http proxy set peer name).
+    (Jakub Zelenka)
+
+- PDO ODBC:
+  . Fix memory leak if WideCharToMultiByte() fails. (nielsdos)
+
+- PDO Sqlite:
+  . Fixed memory leak with Pdo_Sqlite::createCollation when the callback
+    has an incorrect return type. (David Carlier)
+
+- Phar:
+  . Add missing filter cleanups on phar failure. (nielsdos)
+  . Fixed bug GH-18642 (Signed integer overflow in ext/phar fseek). (nielsdos)
+
+- PHPDBG:
+  . Fix 'phpdbg --help' segfault on shutdown with USE_ZEND_ALLOC=0. (nielsdos)
+
+- PGSQL:
+  . Fix warning not being emitted when failure to cancel a query with
+    pg_cancel_query(). (Girgias)
+
+- Random:
+  . Fix reference type confusion and leak in user random engine.
+    (nielsdos, timwolla)
+
+- Readline:
+  . Fix memory leak when calloc() fails in php_readline_completion_cb().
+    (nielsdos)
+
+- SimpleXML:
+  . Fixed bug GH-18597 (Heap-buffer-overflow in zend_alloc.c when assigning
+    string with UTF-8 bytes). (nielsdos)
+
+- Soap:
+  . Fix memory leaks in php_http.c when call_user_function() fails. (nielsdos)
+
+- Tidy:
+  . Fix memory leak in tidy output handler on error. (nielsdos)
+  . Fix tidyOptIsReadonly deprecation, using tidyOptGetCategory. (David Carlier)
+
+06 Jun 2025, PHP 8.4.8
+
+- Core:
+  . Fixed GH-18480 (array_splice with large values for offset/length arguments).
+    (nielsdos/David Carlier)
+  . Partially fixed GH-18572 (nested object comparisons leading to stack overflow).
+    (David Carlier)
+  . Fixed OSS-Fuzz #417078295. (nielsdos)
+  . Fixed OSS-Fuzz #418106144. (nielsdos)
+
+- Curl:
+  . Fixed GH-18460 (curl_easy_setopt with CURLOPT_USERPWD/CURLOPT_USERNAME/
+    CURLOPT_PASSWORD set the Authorization header when set to NULL).
+    (David Carlier)
+
+- Date:
+  . Fixed bug GH-18076 (Since PHP 8, the date_sun_info() function returns
+    inaccurate sunrise and sunset times, but other calculated times are
+    correct) (JiriJozif).
+  . Fixed bug GH-18481 (date_sunrise with unexpected nan value for the offset).
+    (nielsdos/David Carlier)
+
+- DOM:
+  . Backport lexbor/lexbor#274. (nielsdos, alexpeattie)
+
+- Intl:
+  . Fix various reference issues. (nielsdos)
+
+- LDAP:
+  . Fixed bug GH-18529 (ldap no longer respects TLS_CACERT from ldaprc in
+    ldap_start_tls()). (Remi)
+
+- Opcache:
+  . Fixed bug GH-18417 (Windows SHM reattachment fails when increasing
+    memory_consumption or jit_buffer_size). (nielsdos)
+  . Fixed bug GH-18297 (Exception not handled when jit guard is triggered).
+    (Arnaud)
+  . Fixed bug GH-18408 (Snapshotted poly_func / poly_this may be spilled).
+    (Arnaud)
+  . Fixed bug GH-18567 (Preloading with internal class alias triggers assertion
+    failure). (nielsdos)
+  . Fixed bug GH-18534 (FPM exit code 70 with enabled opcache and hooked
+    properties in traits). (nielsdos)
+  . Fix leak of accel_globals->key. (nielsdos)
+
+- OpenSSL:
+  . Fix missing checks against php_set_blocking() in xp_ssl.c. (nielsdos)
+
+- SPL:
+  . Fixed bug GH-18421 (Integer overflow with large numbers in LimitIterator).
+    (nielsdos)
+
+- Standard:
+  . Fixed bug GH-17403 (Potential deadlock when putenv fails). (nielsdos)
+  . Fixed bug GH-18400 (http_build_query type error is inaccurate). (nielsdos)
+  . Fixed bug GH-18509 (Dynamic calls to assert() ignore zend.assertions).
+    (timwolla)
+
+- Windows:
+  . Fix leak+crash with sapi_windows_set_ctrl_handler(). (nielsdos)
+
+- Zip:
+  . Fixed bug GH-18431 (Registering ZIP progress callback twice doesn't work).
+    (nielsdos)
+  . Fixed bug GH-18438 (Handling of empty data and errors in
+    ZipArchive::addPattern). (nielsdos)
+
+24 Apr 2025, PHP 8.4.7
+
+- Core:
+  . Fixed bug GH-18038 (Lazy proxy calls magic methods twice). (Arnaud)
+  . Fixed bug GH-18209 (Use-after-free in extract() with EXTR_REFS). (ilutov)
+  . Fixed bug GH-18268 (Segfault in array_walk() on object with added property
+    hooks). (ilutov)
+  . Fixed bug GH-18304 (Changing the properties of a DateInterval through
+    dynamic properties triggers a SegFault). (nielsdos)
+  . Fix some leaks in php_scandir. (nielsdos)
+
+- DBA:
+  . FIxed bug GH-18247 dba_popen() memory leak on invalid path. (David Carlier)
+
+- Filter:
+  . Fixed bug GH-18309 (ipv6 filter integer overflow). (nielsdos)
+
+- GD:
+  . Fixed imagecrop() overflow with rect argument with x/width y/heigh usage
+    in gdImageCrop(). (David Carlier)
+  . Fixed GH-18243 imagettftext() overflow/underflow on font size value.
+    (David Carlier)
+
+- Intl:
+  . Fix reference support for intltz_get_offset(). (nielsdos)
+
+- LDAP:
+  . Fixed bug GH-17776 (LDAP_OPT_X_TLS_* options can't be overridden). (Remi)
+  . Fix NULL deref on high modification key. (nielsdos)
+
+- libxml:
+  . Fixed custom external entity loader returning an invalid resource leading
+    to a confusing TypeError message. (Girgias)
+
+- Opcache:
+  . Fixed bug GH-18294 (assertion failure zend_jit_ir.c). (nielsdos)
+  . Fixed bug GH-18289 (Fix segfault in JIT). (Florian Engelhardt)
+  . Fixed bug GH-18136 (tracing JIT floating point register clobbering on
+    Windows and ARM64). (nielsdos)
+
+- OpenSSL:
+  . Fix memory leak in openssl_sign() when passing invalid algorithm.
+    (nielsdos)
+  . Fix potential leaks when writing to BIO fails. (nielsdos)
+
+- PDO Firebird:
+  . Fixed bug GH-18276 (persistent connection - "zend_mm_heap corrupted"
+    with setAttribute()) (SakiTakamachi).
+  . Fixed bug GH-17383 (PDOException has wrong code and message since PHP 8.4)
+    (SakiTakamachi).
+
+- PDO Sqlite:
+  . Fix memory leak on error return of collation callback. (nielsdos)
+
+- PgSql:
+  . Fix uouv in pg_put_copy_end(). (nielsdos)
+
+- SPL:
+  . Fixed bug GH-18322 (SplObjectStorage debug handler mismanages memory).
+    (nielsdos)
+
+- Standard:
+  . Fixed bug GH-18145 (php8ts crashes in php_clear_stat_cache()).
+    (Jakub Zelenka)
+  . Fix resource leak in iptcembed() on error. (nielsdos)
+
+- Tests:
+  . Address deprecated PHP 8.4 session options to prevent test failures.
+    (willvar)
+
+- Zip:
+  . Fix uouv when handling empty options in ZipArchive::addGlob(). (nielsdos)
+  . Fix memory leak when handling a too long path in ZipArchive::addGlob().
+    (nielsdos)
+
+10 Apr 2025, PHP 8.4.6
+
+- BCMath:
+  . Fixed pointer subtraction for scale. (SakiTakamachi)
+
+- Core:
+  . Fixed property hook backing value access in multi-level inheritance.
+    (ilutov)
+  . Fixed accidentally inherited default value in overridden virtual properties.
+    (ilutov)
+  . Fixed bug GH-17376 (Broken JIT polymorphism for property hooks added to
+    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)
+  . Fixed bug GH-17988 (Incorrect handling of hooked props without get hook in
+    get_object_vars()). (ilutov)
+  . Fixed bug GH-17998 (Skipped lazy object initialization on primed
+    SIMPLE_WRITE cache). (ilutov)
+  . Fixed bug GH-17998 (Assignment to backing value in set hook of lazy proxy
+    calls hook again). (ilutov)
+  . Fixed bug GH-17961 (use-after-free during dl()'ed module class destruction).
+    (Arnaud)
+  . Fixed bug GH-15367 (dl() of module with aliased class crashes in shutdown).
+    (Arnaud)
+  . Fixed OSS-Fuzz #403308724. (nielsdos)
+  . Fixed bug GH-13193 again (Significant performance degradation in 'foreach').
+    (nielsdos)
+
+- DBA:
+  . Fixed assertion violation when opening the same file with dba_open
+    multiple times. (chschneider)
+
+- DOM:
+  . Fixed bug GH-17991 (Assertion failure dom_attr_value_write). (nielsdos)
+  . Fix weird unpack behaviour in DOM. (nielsdos)
+  . Fixed bug GH-18090 (DOM: Svg attributes and tag names are being lowercased).
+    (nielsdos)
+  . Fix xinclude destruction of live attributes. (nielsdos)
+
+- Fuzzer:
+  . Fixed bug GH-18081 (Memory leaks in error paths of fuzzer SAPI).
+    (Lung-Alexandra)
+
+- GD:
+  . Fixed bug GH-17984 (calls with arguments as array with references).
+    (David Carlier)
+
+- LDAP:
+  . Fixed bug GH-18015 (Error messages for ldap_mod_replace are confusing).
+    (nielsdos)
+
+- Mbstring:
+  . Fixed bug GH-17989 (mb_output_handler crash with unset
+    http_output_conv_mimetypes). (nielsdos)
+
+- Opcache:
+  . Fixed bug GH-15834 (Segfault with hook "simple get" cache slot and minimal
+    JIT). (nielsdos)
+  . Fixed bug GH-17966 (Symfony JIT 1205 assertion failure). (nielsdos)
+  . Fixed bug GH-18037 (SEGV Zend/zend_execute.c). (nielsdos)
+  . Fixed bug GH-18050 (IN_ARRAY optimization in DFA pass is broken). (ilutov)
+  . Fixed bug GH-18113 (stack-buffer-overflow ext/opcache/jit/ir/ir_sccp.c).
+    (nielsdos)
+  . Fixed bug GH-18112 (NULL access with preloading and INI option). (nielsdos)
+  . Fixed bug GH-18107 (Opcache CFG jmp optimization with try-finally breaks
+    the exception table). (nielsdos)
+
+- PDO:
+  . Fix memory leak when destroying PDORow. (nielsdos)
+
+- PGSQL:
+  . Fixed bug GH-18148 (pg_copy_from() regression with explicit \n terminator
+    due to wrong offset check). (David Carlier)
+
+- Standard:
+  . Fix memory leaks in array_any() / array_all(). (nielsdos)
+
+- SOAP:
+  . Fixed bug #66049 (Typemap can break parsing in parse_packet_soap leading to
+    a segfault) . (Remi)
+
+- SPL:
+  . Fixed bug GH-18018 (RC1 data returned from offsetGet causes UAF in
+    ArrayObject). (nielsdos)
+
+- Treewide:
+  . Fixed bug GH-17736 (Assertion failure zend_reference_destroy()). (nielsdos)
+
+- Windows:
+  . Fixed bug GH-17836 (zend_vm_gen.php shouldn't break on Windows line
+    endings). (DanielEScherzer)
+
+27 Feb 2025, PHP 8.4.5
+
+- BCMath:
+  . Fixed bug GH-17398 (bcmul memory leak). (SakiTakamachi)
+
+- Core:
+  . Fixed bug GH-17623 (Broken stack overflow detection for variable
+    compilation). (ilutov)
+  . Fixed bug GH-17618 (UnhandledMatchError does not take
+    zend.exception_ignore_args=1 into account). (timwolla)
+  . Fix fallback paths in fast_long_{add,sub}_function. (nielsdos)
+  . Fixed bug OSS-Fuzz #391975641 (Crash when accessing property backing value
+    by reference). (ilutov)
+  . Fixed bug GH-17718 (Calling static methods on an interface that has
+    `__callStatic` is allowed). (timwolla)
+  . Fixed bug GH-17713 (ReflectionProperty::getRawValue() and related methods
+    may call hooks of overridden properties). (Arnaud)
+  . Fixed bug GH-17916 (Final abstract properties should error).
+    (DanielEScherzer)
+  . Fixed bug GH-17866 (zend_mm_heap corrupted error after upgrading from
+    8.4.3 to 8.4.4). (nielsdos)
+  . Fixed GHSA-rwp7-7vc6-8477 (Reference counting in php_request_shutdown
+    causes Use-After-Free). (CVE-2024-11235) (ilutov)
+
+- DOM:
+  . Fixed bug GH-17609 (Typo in error message: Dom\NO_DEFAULT_NS instead of
+    Dom\HTML_NO_DEFAULT_NS). (nielsdos)
+  . Fixed bug GH-17802 (\Dom\HTMLDocument querySelector attribute name is case
+    sensitive in HTML). (nielsdos)
+  . Fixed bug GH-17847 (xinclude destroys live node). (nielsdos)
+  . Fix using Dom\Node with Dom\XPath callbacks. (nielsdos)
+
+- FFI:
+  . Fix FFI Parsing of Pointer Declaration Lists. (davnotdev)
+
+- FPM:
+  . Fixed bug GH-17643 (FPM with httpd ProxyPass encoded PATH_INFO env).
+    (Jakub Zelenka)
+
+- GD:
+  . Fixed bug GH-17703 (imagescale with both width and height negative values
+    triggers only an Exception on width). (David Carlier)
+  . Fixed bug GH-17772 (imagepalettetotruecolor crash with memory_limit=2M).
+    (David Carlier)
+
+- LDAP:
+  . Fixed bug GH-17704 (ldap_search fails when $attributes contains a
+    non-packed array with numerical keys). (nielsdos, 7u83)
+
+- LibXML:
+  . Fixed GHSA-wg4p-4hqh-c3g9 (Reocurrence of #72714). (nielsdos)
+  . Fixed GHSA-p3x9-6h7p-cgfc (libxml streams use wrong `content-type` header
+    when requesting a redirected resource). (CVE-2025-1219) (timwolla)
+
+- MBString:
+  . Fixed bug GH-17503 (Undefined float conversion in mb_convert_variables).
+    (cmb)
+
+- Opcache:
+  . Fixed bug GH-17654 (Multiple classes using same trait causes function
+    JIT crash). (nielsdos)
+  . Fixed bug GH-17577 (JIT packed type guard crash). (nielsdos, Dmitry)
+  . Fixed bug GH-17747 (Exception on reading property in register-based
+    FETCH_OBJ_R breaks JIT). (Dmitry, nielsdos)
+  . Fixed bug GH-17715 (Null pointer deref in observer API when calling
+    cases() method on preloaded enum). (Bob)
+  . Fixed bug GH-17868 (Cannot allocate memory with tracing JIT on 8.4.4).
+    (nielsdos)
+
+- PDO_SQLite:
+  . Fixed GH-17837 ()::getColumnMeta() on unexecuted statement segfaults).
+    (cmb)
+  . Fix cycle leak in sqlite3 setAuthorizer(). (nielsdos)
+  . Fix memory leaks in pdo_sqlite callback registration. (nielsdos)
+
+- Phar:
+  . Fixed bug GH-17808: PharFileInfo refcount bug. (nielsdos)
+
+- PHPDBG:
+  . Partially fixed bug GH-17387 (Trivial crash in phpdbg lexer). (nielsdos)
+  . Fix memory leak in phpdbg calling registered function. (nielsdos)
+
+- Reflection:
+  . Fixed bug GH-15902 (Core dumped in ext/reflection/php_reflection.c).
+    (DanielEScherzer)
+  . Fixed missing final and abstract flags when dumping properties.
+    (DanielEScherzer)
+
+- Standard:
+  . Fixed bug #72666 (stat cache clearing inconsistent between file:// paths
+    and plain paths). (Jakub Zelenka)
+
+- Streams:
+  . Fixed bug GH-17650 (realloc with size 0 in user_filters.c). (nielsdos)
+  . Fix memory leak on overflow in _php_stream_scandir(). (nielsdos)
+  . Fixed GHSA-hgf5-96fm-v528 (Stream HTTP wrapper header check might omit
+    basic auth header). (CVE-2025-1736) (Jakub Zelenka)
+  . Fixed GHSA-52jp-hrpf-2jff (Stream HTTP wrapper truncate redirect location
+    to 1024 bytes). (CVE-2025-1861) (Jakub Zelenka)
+  . Fixed GHSA-pcmh-g36c-qc44 (Streams HTTP wrapper does not fail for headers
+    without colon). (CVE-2025-1734) (Jakub Zelenka)
+  . Fixed GHSA-v8xr-gpvj-cx9g (Header parser of `http` stream wrapper does not
+    handle folded headers). (CVE-2025-1217) (Jakub Zelenka)
+
+- Windows:
+  . Fixed phpize for Windows 11 (24H2). (bwoebi)
+  . Fixed GH-17855 (CURL_STATICLIB flag set even if linked with shared lib).
+    (cmb)
+
+- Zlib:
+  . Fixed bug GH-17745 (zlib extension incorrectly handles object arguments).
+    (nielsdos)
+  . Fix memory leak when encoding check fails. (nielsdos)
+  . Fix zlib support for large files. (nielsdos)
+
+13 Feb 2025, PHP 8.4.4
+
+- Core:
+  . Fixed bug GH-17234 (Numeric parent hook call fails with assertion).
+    (nielsdos)
+  . Fixed bug GH-16892 (ini_parse_quantity() fails to parse inputs starting
+    with 0x0b). (nielsdos)
+  . Fixed bug GH-16886 (ini_parse_quantity() fails to emit warning for 0x+0).
+    (nielsdos)
+  . Fixed bug GH-17222 (__PROPERTY__ magic constant does not work in all
+    constant expression contexts). (ilutov)
+  . Fixed bug GH-17214 (Relax final+private warning for trait methods with
+    inherited final). (ilutov)
+  . Fixed NULL arithmetic during system program execution on Windows. (cmb,
+    nielsdos)
+  . Fixed potential OOB when checking for trailing spaces on Windows. (cmb)
+  . Fixed bug GH-17408 (Assertion failure Zend/zend_exceptions.c).
+    (nielsdos, ilutov)
+  . Fix may_have_extra_named_args flag for ZEND_AST_UNPACK. (nielsdos)
+  . Fix NULL arithmetic in System V shared memory emulation for Windows. (cmb)
+  . Fixed bug GH-17597 (#[\Deprecated] does not work for __call() and
+    __callStatic()). (timwolla)
+
+- DOM:
+  . Fixed bug GH-17397 (Assertion failure ext/dom/php_dom.c). (nielsdos)
+  . Fixed bug GH-17486 (Incorrect error line numbers reported in
+    Dom\HTMLDocument::createFromString). (nielsdos)
+  . Fixed bug GH-17481 (UTF-8 corruption in \Dom\HTMLDocument). (nielsdos)
+  . Fixed bug GH-17500 (Segfault with requesting nodeName on nameless doctype).
+    (nielsdos)
+  . Fixed bug GH-17485 (upstream fix, Self-closing tag on void elements
+    shouldn't be a parse error/warning in \Dom\HTMLDocument). (lexborisov)
+  . Fixed bug GH-17572 (getElementsByTagName returns collections with
+    tagName-based indexing). (nielsdos)
+
+- Enchant:
+  . Fix crashes in enchant when passing null bytes. (nielsdos)
+
+- FTP:
+  . Fixed bug GH-16800 (ftp functions can abort with EINTR). (nielsdos)
+
+- GD:
+  . Fixed bug GH-17349 (Tiled truecolor filling looses single color
+    transparency). (cmb)
+  . Fixed bug GH-17373 (imagefttext() ignores clipping rect for palette
+    images). (cmb)
+  . Ported fix for libgd 223 (gdImageRotateGeneric() does not properly
+    interpolate). (cmb)
+  . Added support for reading GIFs without colormap to bundled libgd. (Andrew
+    Burley, cmb)
+
+- Gettext:
+  . Fixed bug GH-17400 (bindtextdomain SEGV on invalid domain).
+    (David Carlier)
+
+- Intl:
+  . Fixed bug GH-11874 (intl causing segfault in docker images). (nielsdos)
+
+- Opcache:
+  . Fixed bug GH-15981 (Segfault with frameless jumps and minimal JIT).
+    (nielsdos)
+  . Fixed bug GH-17307 (Internal closure causes JIT failure). (nielsdos)
+  . Fixed bug GH-17428 (Assertion failure ext/opcache/jit/zend_jit_ir.c:8940).
+    (nielsdos)
+  . Fixed bug GH-17564 (Potential UB when reading from / writing to struct
+    padding). (ilutov)
+
+- PCNTL:
+  . Fixed pcntl_setcpuaffinity exception type from ValueError to TypeError for
+    the cpu mask argument with entries type different than int/string.
+    (David Carlier)
+
+- PCRE:
+  . Fixed bug GH-17122 (memory leak in regex). (nielsdos)
+
+- PDO:
+  . Fixed a memory leak when the GC is used to free a PDOStatment. (Girgias)
+  . Fixed a crash in the PDO Firebird Statement destructor. (nielsdos)
+  . Fixed UAFs when changing default fetch class ctor args. (Girgias, nielsdos)
+
+- PgSql:
+  . Fixed build failure when the constant PGRES_TUPLES_CHUNK is not present
+    in the system. (chschneider)
+
+- Phar:
+  . Fixed bug GH-17518 (offset overflow phar extractTo()). (nielsdos)
+
+- PHPDBG:
+  . Fix crashes in function registration + test. (nielsdos, Girgias)
+
+- Session:
+  . Fix type confusion with session SID constant. (nielsdos)
+  . Fixed bug GH-17541 (ext/session NULL pointer dereferencement during
+    ID reset). (Girgias)
+
+- SimpleXML:
+  . Fixed bug GH-17409 (Assertion failure Zend/zend_hash.c:1730). (nielsdos)
+
+- SNMP:
+  . Fixed bug GH-17330 (SNMP::setSecurity segfault on closed session).
+    (David Carlier)
+
+- SPL:
+  . Fixed bug GH-15833 (Segmentation fault (access null pointer) in
+    ext/spl/spl_array.c). (nielsdos)
+  . Fixed bug GH-17516 (SplFileTempObject::getPathInfo() Undefined behavior
+    on invalid class). (David Carlier)
+
+- Standard:
+  . Fixed bug GH-17447 (Assertion failure when array popping a self addressing
+    variable). (nielsdos)
+
+- Windows:
+  . Fixed clang compiler detection. (cmb)
+
+- Zip:
+  . Fixed bug GH-17139 (Fix zip_entry_name() crash on invalid entry).
+    (nielsdos)
+
+16 Jan 2025, PHP 8.4.3
+
+- BcMath:
+  . Fixed bug GH-17049 (Correctly compare 0 and -0). (Saki Takamachi)
+  . Fixed bug GH-17061 (Now Number::round() does not remove trailing zeros).
+    (Saki Takamachi)
+  . Fixed bug GH-17064 (Correctly round rounding mode with zero edge case).
+    (Saki Takamachi)
+  . Fixed bug GH-17275 (Fixed the calculation logic of dividend scale).
+    (Saki Takamachi)
+
+- Core:
+  . Fixed bug OSS-Fuzz #382922236 (Duplicate dynamic properties in hooked object
+    iterator properties table). (ilutov)
+  . Fixed unstable get_iterator pointer for hooked classes in shm on Windows.
+    (ilutov)
+  . Fixed bug GH-17106 (ZEND_MATCH_ERROR misoptimization). (ilutov)
+  . Fixed bug GH-17162 (zend_array_try_init() with dtor can cause engine UAF).
+    (nielsdos)
+  . Fixed bug GH-17101 (AST->string does not reproduce constructor property
+    promotion correctly). (nielsdos)
+  . Fixed bug GH-17200 (Incorrect dynamic prop offset in hooked prop iterator).
+    (ilutov)
+  . Fixed bug GH-17216 (Trampoline crash on error). (nielsdos)
+
+- DBA:
+  . Skip test if inifile is disabled. (orlitzky)
+
+- DOM:
+  . Fixed bug GH-17145 (DOM memory leak). (nielsdos)
+  . Fixed bug GH-17201 (Dom\TokenList issues with interned string replace).
+    (nielsdos)
+  . Fixed bug GH-17224 (UAF in importNode). (nielsdos)
+
+- Embed:
+  . Make build command for program using embed portable. (dunglas)
+
+- FFI:
+  . Fixed bug #79075 (FFI header parser chokes on comments). (nielsdos)
+  . Fix memory leak on ZEND_FFI_TYPE_CHAR conversion failure. (nielsdos)
+  . Fixed bug GH-16013 and bug #80857 (Big endian issues). (Dmitry, nielsdos)
+
+- Fileinfo:
+  . Fixed bug GH-17039 (PHP 8.4: Incorrect MIME content type). (nielsdos)
+
+- FPM:
+  . Fixed bug GH-13437 (FPM: ERROR: scoreboard: failed to lock (already
+    locked)). (Jakub Zelenka)
+  . Fixed bug GH-17112 (Macro redefinitions). (cmb, nielsdos)
+  . Fixed bug GH-17208 (bug64539-status-json-encoding.phpt fail on 32-bits).
+    (nielsdos)
+
+- GD:
+  . Fixed bug GH-16255 (Unexpected nan value in ext/gd/libgd/gd_filter.c).
+    (nielsdos, cmb)
+  . Ported fix for libgd bug 276 (Sometimes pixels are missing when storing
+    images as BMPs). (cmb)
+
+- Gettext:
+  . Fixed bug GH-17202 (Segmentation fault ext/gettext/gettext.c
+    bindtextdomain()). (Michael Orlitzky)
+
+- Iconv:
+  . Fixed bug GH-17047 (UAF on iconv filter failure). (nielsdos)
+
+- LDAP:
+  . Fixed bug GH-17280 (ldap_search() fails when $attributes array has holes).
+    (nielsdos)
+
+- LibXML:
+  . Fixed bug GH-17223 (Memory leak in libxml encoding handling). (nielsdos)
+
+- MBString:
+  . Fixed bug GH-17112 (Macro redefinitions). (nielsdos, cmb)
+
+- Opcache:
+  . opcache_get_configuration() properly reports jit_prof_threshold. (cmb)
+  . Fixed bug GH-17140 (Assertion failure in JIT trace exit with
+    ZEND_FETCH_DIM_FUNC_ARG). (nielsdos, Dmitry)
+  . Fixed bug GH-17151 (Incorrect RC inference of op1 of FETCH_OBJ and
+    INIT_METHOD_CALL). (Dmitry, ilutov)
+  . Fixed bug GH-17246 (GC during SCCP causes segfault). (Dmitry)
+  . Fixed bug GH-17257 (UBSAN warning in ext/opcache/jit/zend_jit_vm_helpers.c).
+    (nielsdos, Dmitry)
+
+- PCNTL:
+  . Fix memory leak in cleanup code of pcntl_exec() when a non stringable
+    value is encountered past the first entry. (Girgias)
+
+- PgSql:
+  . Fixed bug GH-17158 (pg_fetch_result Shows Incorrect ArgumentCountError
+    Message when Called With 1 Argument). (nielsdos)
+  . Fixed further ArgumentCountError for calls with flexible
+    number of arguments. (David Carlier)
+
+- Phar:
+  . Fixed bug GH-17137 (Segmentation fault ext/phar/phar.c). (nielsdos)
+
+- SimpleXML:
+  . Fixed bug GH-17040 (SimpleXML's unset can break DOM objects). (nielsdos)
+  . Fixed bug GH-17153 (SimpleXML crash when using autovivification on
+    document). (nielsdos)
+
+- Sockets:
+  . Fixed bug GH-16276 (socket_strerror overflow handling with INT_MIN).
+    (David Carlier / cmb)
+  . Fixed overflow on SO_LINGER values setting, strengthening values check
+    on SO_SNDTIMEO/SO_RCVTIMEO for socket_set_option().
+    (David Carlier)
+
+- SPL:
+  . Fixed bug GH-17198 (SplFixedArray assertion failure with get_object_vars).
+    (nielsdos)
+  . Fixed bug GH-17225 (NULL deref in spl_directory.c). (nielsdos)
+
+- Streams:
+  . Fixed bug GH-17037 (UAF in user filter when adding existing filter name due
+    to incorrect error handling). (nielsdos)
+  . Fixed bug GH-16810 (overflow on fopen HTTP wrapper timeout value).
+    (David Carlier)
+  . Fixed bug GH-17067 (glob:// wrapper doesn't cater to CWD for ZTS builds).
+    (cmb)
+
+- Windows:
+  . Hardened proc_open() against cmd.exe hijacking. (cmb)
+
+- XML:
+  . Fixed bug GH-1718 (unreachable program point in zend_hash). (nielsdos)
+
+19 Dec 2024, PHP 8.4.2
+
+- BcMath:
+  . Fixed bug GH-16978 (Avoid unnecessary padding with leading zeros).
+    (Saki Takamachi)
+
+- COM:
+  . Fixed bug GH-16991 (Getting typeinfo of non DISPATCH variant segfaults).
+    (cmb)
+
+- Core:
+  . Fixed bug GH-16344 (setRawValueWithoutLazyInitialization() and
+    skipLazyInitialization() may change initialized proxy). (Arnaud)
+  . Fix is_zend_ptr() huge block comparison. (nielsdos)
+  . Fixed potential OOB read in zend_dirname() on Windows. (cmb)
+  . Fixed bug GH-15964 (printf() can strip sign of -INF). (divinity76, cmb)
+
+- Curl:
+  . Fix various memory leaks in curl mime handling. (nielsdos)
+
+- DBA:
+  . Fixed bug GH-16990 (dba_list() is now zero-indexed instead of using
+    resource ids) (kocsismate)
+
+- DOM:
+  . Fixed bug GH-16906 (Reloading document can cause UAF in iterator).
+    (nielsdos)
+
+- FPM:
+  . Fixed bug GH-16932 (wrong FPM status output). (Jakub Zelenka, James Lucas)
+
+- GMP:
+  . Fixed bug GH-16890 (array_sum() with GMP can loose precision (LLP64)).
+    (cmb)
+
+- Opcache:
+  . Fixed bug GH-16851 (JIT_G(enabled) not set correctly on other threads).
+    (dktapps)
+  . Fixed bug GH-16902 (Set of opcache tests fail zts+aarch64). (nielsdos)
+  . Fixed bug GH-16879 (JIT dead code skipping does not update call_level).
+    (nielsdos)
+
+- SAPI:
+  . Fixed bug GH-16998 (UBSAN warning in rfc1867). (nielsdos)
+
+- PHPDBG:
+  . Fixed bug GH-15208 (Segfault with breakpoint map and phpdbg_clear()).
+    (nielsdos)
+
+- Standard:
+  . Fixed bug GH-16905 (Internal iterator functions can't handle UNDEF
+    properties). (nielsdos)
+  . Fixed bug GH-16957 (Assertion failure in array_shift with
+    self-referencing array). (nielsdos)
+
+- Streams:
+  . Fixed network connect poll interuption handling. (Jakub Zelenka)
+
+- Windows:
+  . Fixed bug GH-16849 (Error dialog causes process to hang). (cmb)
+  . Windows Server 2025 is now properly reported. (cmb)
+
+21 Nov 2024, PHP 8.4.1
+
+- BcMath:
+  . [RFC] Add bcfloor, bcceil and bcround to BCMath. (Saki Takamachi)
+  . Improve performance. (Saki Takamachi, nielsdos)
+  . Adjust bcround()'s $mode parameter to only accept the RoundingMode
+    enum. (timwolla, saki)
+  . Fixed LONG_MAX in BCMath ext. (Saki Takamachi)
+  . Fixed bcdiv() div by one. (Saki Takamachi)
+  . [RFC] Support object types in BCMath. (Saki Takamachi)
+  . bcpow() performance improvement. (Jorg Sowa)
+  . ext/bcmath: Check for scale overflow. (SakiTakamachi)
+  . [RFC] ext/bcmath: Added bcdivmod. (SakiTakamachi)
+  . Fix GH-15968 (Avoid converting objects to strings in operator calculations).
+    (SakiTakamachi)
+  . Fixed bug GH-16265 (Added early return case when result is 0)
+    (Saki Takamachi).
+  . Fixed bug GH-16262 (Fixed a bug where size_t underflows) (Saki Takamachi).
+  . Fixed GH-16236 (Fixed a bug in BcMath\Number::pow() and bcpow() when
+    raising negative powers of 0) (Saki Takamachi).
+
+- Core:
+  . Added zend_call_stack_get implementation for NetBSD, DragonFlyBSD,
+    Solaris and Haiku. (David Carlier)
+  . Enabled ifunc checks on FreeBSD from the 12.x releases. (Freaky)
+  . Changed the type of PHP_DEBUG and PHP_ZTS constants to bool. (haszi)
+  . Fixed bug GH-13142 (Undefined variable name is shortened when contains \0).
+    (nielsdos)
+  . Fixed bug GH-13178 (Iterator positions incorrect when converting packed
+    array to hashed). (ilutov)
+  . Fixed zend fiber build for solaris default mode (32 bits). (David Carlier)
+  . Fixed zend call stack size for macOs/arm64. (David Carlier)
+  . Added support for Zend Max Execution Timers on FreeBSD. (Kévin Dunglas)
+  . Ensure fiber stack is not backed by THP. (crrodriguez)
+  . Implement GH-13609 (Dump wrapped object in WeakReference class). (nielsdos)
+  . Added sparc64 arch assembly support for zend fiber. (Claudio Jeker)
+  . Fixed GH-13581 no space available for TLS on NetBSD. (Paul Ripke)
+  . Added fiber Sys-V loongarch64 support. (qiangxuhui)
+  . Adjusted closure names to include the parent function's name. (timwolla)
+  . Improve randomness of uploaded file names and files created by tempnam().
+    (Arnaud)
+  . Added gc and shutdown callbacks to zend_mm custom handlers.
+    (Florian Engelhardt)
+  . Fixed bug GH-14650 (Compute the size of pages before allocating memory).
+    (Julien Voisin)
+  . Fixed bug GH-11928 (The --enable-re2c-cgoto doesn't add the -g flag).
+    (Peter Kokot)
+  . Added the #[\Deprecated] attribute. (beberlei, timwolla)
+  . Fixed GH-11389 (Allow suspending fibers in destructors). (Arnaud, trowski)
+  . Fixed bug GH-14801 (Fix build for armv7). (andypost)
+  . Implemented property hooks RFC. (ilutov)
+  . Fix GH-14978 (The xmlreader extension phpize build). (Peter Kokot)
+  . Throw Error exception when encountering recursion during comparison, rather
+    than fatal error. (ilutov)
+  . Added missing cstddef include for C++ builds. (cmb)
+  . Updated build system scripts config.guess to 2024-07-27 and config.sub to
+    2024-05-27. (Peter Kokot)
+  . Fixed bug GH-15240 (Infinite recursion in trait hook). (ilutov)
+  . Fixed bug GH-15140 (Missing variance check for abstract set with asymmetric
+    type). (ilutov)
+  . Fixed bug GH-15181 (Disabled output handler is flushed again). (cmb)
+  . Passing E_USER_ERROR to trigger_error() is now deprecated. (Girgias)
+  . Fixed bug GH-15292 (Dynamic AVX detection is broken for MSVC). (nielsdos)
+  . Using "_" as a class name is now deprecated. (Girgias)
+  . Exiting a namespace now clears seen symbols. (ilutov)
+  . The exit (and die) language constructs now behave more like a function.
+    They can be passed liked callables, are affected by the strict_types
+    declare statement, and now perform the usual type coercions instead of
+    casting any non-integer value to a string.
+    As such, passing invalid types to exit/die may now result in a TypeError
+    being thrown. (Girgias)
+  . Fixed bug GH-15438 (Hooks on constructor promoted properties without
+    visibility are ignored). (ilutov)
+  . Fixed bug GH-15419 (Missing readonly+hook incompatibility check for readonly
+    classes). (ilutov)
+  . Fixed bug GH-15187 (Various hooked object iterator issues). (ilutov)
+  . Fixed bug GH-15456 (Crash in get_class_vars() on virtual properties).
+    (ilutov)
+  . Fixed bug GH-15501 (Windows HAVE_<header>_H macros defined to 1 or
+    undefined). (Peter Kokot)
+  . Implemented asymmetric visibility for properties. (ilutov)
+  . Fixed bug GH-15644 (Asymmetric visibility doesn't work with hooks). (ilutov)
+  . Implemented lazy objects RFC. (Arnaud)
+  . Fixed bug GH-15686 (Building shared iconv with external iconv library).
+    (Peter Kokot, zeriyoshi)
+  . Fixed missing error when adding asymmetric visibility to unilateral virtual
+    property. (ilutov)
+  . Fixed bug GH-15693 (Unnecessary include in main.c bloats binary).
+    (nielsdos)
+  . Fixed bug GH-15731 (AllowDynamicProperties validation should error on
+    enums). (DanielEScherzer)
+  . Fixed bug GH-16040 (Use-after-free of object released in hook). (ilutov)
+  . Fixed bug GH-16026 (Reuse of dtor fiber during shutdown). (Arnaud)
+  . Fixed bug GH-15999 (zend_std_write_property() assertion failure with lazy
+    objects). (Arnaud)
+  . Fixed bug GH-15960 (Foreach edge cases with lazy objects). (Arnaud)
+  . Fixed bug GH-16185 (Various hooked object iterator issues). (ilutov)
+  . Fixed bug OSS-Fuzz #371445205 (Heap-use-after-free in attr_free).
+    (nielsdos)
+  . Fixed missing error when adding asymmetric visibility to static properties.
+    (ilutov)
+  . Fixed bug OSS-Fuzz #71407 (Null-dereference WRITE in
+    zend_lazy_object_clone). (Arnaud)
+  . Fixed bug GH-16574 (Incorrect error "undefined method" messages).
+    (nielsdos)
+  . Fixed bug GH-16577 (EG(strtod_state).freelist leaks with opcache.preload).
+    (nielsdos)
+  . Fixed bug GH-16615 (Assertion failure in zend_std_read_property). (Arnaud)
+  . Fixed bug GH-16342 (Added ReflectionProperty::isLazy()). (Arnaud)
+  . Fixed bug GH-16725 (Incorrect access check for non-hooked props in hooked
+    object iterator). (ilutov)
+
+- Curl:
+  . Deprecated the CURLOPT_BINARYTRANSFER constant. (divinity76)
+  . Bumped required libcurl version to 7.61.0. (Ayesh)
+  . Added feature_list key to the curl_version() return value. (Ayesh)
+  . Added constants CURL_HTTP_VERSION_3 (libcurl 7.66) and CURL_HTTP_VERSION_3ONLY
+    (libcurl 7.88) as options for CURLOPT_HTTP_VERSION (Ayesh Karunaratne)
+  . Added CURLOPT_TCP_KEEPCNT to set the number of probes to send before
+    dropping the connection. (David Carlier)
+  . Added CURLOPT_PREREQFUNCTION Curl option to set a custom callback
+    after the connection is established, but before the request is
+    performed. (Ayesh Karunaratne)
+  . Added CURLOPT_SERVER_RESPONSE_TIMEOUT, which was formerly known as
+    CURLOPT_FTP_RESPONSE_TIMEOUT. (Ayesh Karunaratne)
+  . The CURLOPT_DNS_USE_GLOBAL_CACHE option is now silently ignored. (Ayesh Karunaratne)
+  . Added CURLOPT_DEBUGFUNCTION as a Curl option. (Ayesh Karunaratne)
+  . Fixed bug GH-16359 (crash with curl_setopt* CURLOPT_WRITEFUNCTION
+    without null callback). (David Carlier)
+  . Fixed bug GH-16723 (CURLMOPT_PUSHFUNCTION issues). (cmb)
+
+- Date:
+  . Added DateTime[Immutable]::createFromTimestamp. (Marc Bennewitz)
+  . Added DateTime[Immutable]::[get|set]Microsecond. (Marc Bennewitz)
+  . Constants SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING, and SUNFUNCS_RET_DOUBLE
+    are now deprecated. (Jorg Sowa)
+  . Fixed bug GH-13773 (DatePeriod not taking into account microseconds for end
+    date). (Mark Bennewitz, Derick)
+
+- DBA:
+  . Passing null or false to dba_key_split() is deprecated. (Grigias)
+
+- Debugging:
+  . Fixed bug GH-15923 (GDB: Python Exception <class 'TypeError'>:
+    exceptions must derive from BaseException). (nielsdos)
+
+- DOM:
+  . Added DOMNode::compareDocumentPosition(). (nielsdos)
+  . Implement #53655 (Improve speed of DOMNode::C14N() on large XML documents).
+    (nielsdos)
+  . Fix cloning attribute with namespace disappearing namespace. (nielsdos)
+  . Implement DOM HTML5 parsing and serialization RFC. (nielsdos)
+  . Fix DOMElement->prefix with empty string creates bogus prefix. (nielsdos)
+  . Handle OOM more consistently. (nielsdos)
+  . Implemented "Improve callbacks in ext/dom and ext/xsl" RFC. (nielsdos)
+  . Added DOMXPath::quote() static method. (divinity76)
+  . Implemented opt-in ext/dom spec compliance RFC. (nielsdos)
+  . Fixed bug #79701 (getElementById does not correctly work with duplicate
+    definitions). (nielsdos)
+  . Implemented "New ext-dom features in PHP 8.4" RFC. (nielsdos)
+  . Fixed GH-14698 (segfault on DOM node dereference). (David Carlier)
+  . Improve support for template elements. (nielsdos)
+  . Fix trampoline leak in xpath callables. (nielsdos)
+  . Throw instead of silently failing when creating a too long text node in
+    (DOM)ParentNode and (DOM)ChildNode. (nielsdos)
+  . Fixed bug GH-15192 (Segmentation fault in dom extension
+    (html5_serializer)). (nielsdos)
+  . Deprecated DOM_PHP_ERR constant. (nielsdos)
+  . Removed DOMImplementation::getFeature(). (nielsdos)
+  . Fixed bug GH-15331 (Element::$substitutedNodeValue test failed). (nielsdos)
+  . Fixed bug GH-15570 (Segmentation fault (access null pointer) in
+    ext/dom/html5_serializer.c). (nielsdos)
+  . Fixed bug GH-13988 (Storing DOMElement consume 4 times more memory in
+    PHP 8.1 than in PHP 8.0). (nielsdos)
+  . Fix XML serializer errata: xmlns="" serialization should be allowed.
+    (nielsdos)
+  . Fixed bug GH-15910 (Assertion failure in ext/dom/element.c). (nielsdos)
+  . Fix unsetting DOM properties. (nielsdos)
+  . Fixed bug GH-16190 (Using reflection to call Dom\Node::__construct
+    causes assertion failure). (nielsdos)
+  . Fix edge-case in DOM parsing decoding. (nielsdos)
+  . Fixed bug GH-16465 (Heap buffer overflow in DOMNode->getElementByTagName).
+    (nielsdos)
+  . Fixed bug GH-16594 (Assertion failure in DOM -> before). (nielsdos)
+
+- Fileinfo:
+  . Update to libmagic 5.45. (nielsdos)
+  . Fixed bug #65106 (PHP fails to compile ext/fileinfo). (Guillaume Outters)
+
+- FPM:
+  . Implement GH-12385 (flush headers without body when calling flush()).
+    (nielsdos)
+  . Added DragonFlyBSD system to the list which set FPM_BACKLOG_DEFAULT
+    to SOMAXCONN. (David Carlier)
+  . /dev/poll events.mechanism for Solaris/Illumos setting had been retired.
+    (David Carlier)
+  . Added memory peak to the scoreboard / status page. (Flávio Heleno)
+
+- FTP:
+  . Removed the deprecated inet_ntoa call support. (David Carlier)
+  . Fixed bug #63937 (Upload speed 10 times slower with PHP). (nielsdos)
+
+- GD:
+  . Fix parameter numbers and missing alpha check for imagecolorset().
+    (Giovanni Giacobbi)
+  . imagepng/imagejpeg/imagewep/imageavif now throw an exception on
+    invalid quality parameter. (David Carlier)
+  . Check overflow/underflow for imagescale/imagefilter. (David Carlier)
+  . Added gdImageClone to bundled libgd. (David Carlier)
+
+- Gettext:
+  . bind_textdomain_codeset, textdomain and d(*)gettext functions
+    now throw an exception on empty domain. (David Carlier)
+
+- GMP:
+  . The GMP class is now final and cannot be extended anymore. (Girgias)
+  . RFC: Change GMP bool cast behavior. (Saki Takamachi)
+
+- Hash:
+  . Changed return type of hash_update() to true. (nielsdos)
+  . Added HashContext::__debugInfo(). (timwolla)
+  . Deprecated passing incorrect data types for options to ext/hash functions.
+    (nielsdos)
+  . Added SSE2 and SHA-NI implementation of SHA-256. (timwolla, Colin Percival,
+    Graham Percival)
+  . Fix GH-15384 (Build fails on Alpine / Musl for amd64). (timwolla)
+  . Fixed bug GH-15742 (php_hash_sha.h incompatible with C++). (cmb)
+
+- IMAP:
+  . Moved to PECL. (Derick Rethans)
+
+- Intl:
+  . Added IntlDateFormatter::PATTERN constant. (David Carlier)
+  . Fixed Numberformatter::__construct when the locale is invalid, now
+    throws an exception. (David Carlier)
+  . Added NumberFormatter::ROUND_TOWARD_ZERO and ::ROUND_AWAY_FROM_ZERO as
+    aliases for ::ROUND_DOWN and ::ROUND_UP. (Jorg Sowa)
+  . Added NumberFormatter::ROUND_HALFODD. (Ayesh Karunaratne)
+  . Added PROPERTY_IDS_UNARY_OPERATOR, PROPERTY_ID_COMPAT_MATH_START and
+    PROPERTY_ID_COMPAT_MATH_CONTINUE constants. (David Carlier)
+  . Added IntlDateFormatter::getIanaID/intltz_get_iana_id method/function.
+    (David Carlier)
+  . Set to C++17 standard for icu 74 and onwards. (David Carlier)
+  . resourcebundle_get(), ResourceBundle::get(), and accessing offsets on a
+    ResourceBundle object now throw:
+    - TypeError for invalid offset types
+    - ValueError for an empty string
+    - ValueError if the integer index does not fit in a signed 32 bit integer
+  . ResourceBundle::get() now has a tentative return type of:
+    ResourceBundle|array|string|int|null
+  . Added the new Grapheme function grapheme_str_split. (youkidearitai)
+  . Added IntlDateFormatter::parseToCalendar. (David Carlier)
+  . Added SpoofChecker::setAllowedChars to set unicode chars ranges.
+    (David Carlier)
+
+- LDAP:
+  . Added LDAP_OPT_X_TLS_PROTOCOL_MAX/LDAP_OPT_X_TLS_PROTOCOL_TLS1_3
+    constants. (StephenWall)
+
+- LibXML:
+  . Added LIBXML_RECOVER constant. (nielsdos)
+  . libxml_set_streams_context() now throws immediately on an invalid context
+    instead of at the use-site. (nielsdos)
+  . Added LIBXML_NO_XXE constant. (nielsdos)
+
+- MBString:
+  . Added mb_trim, mb_ltrim and mb_rtrim. (Yuya Hamada)
+  . Added mb_ucfirst and mb_lcfirst. (Yuya Hamada)
+  . Updated Unicode data tables to Unicode 15.1. (Ayesh Karunaratne)
+  . Fixed bug GH-15824 (mb_detect_encoding(): Argument $encodings contains
+    invalid encoding "UTF8"). (Yuya Hamada)
+  . Updated Unicode data tables to Unicode 16.0. (Ayesh Karunaratne)
+
+- Mysqli:
+  . The mysqli_ping() function and mysqli::ping() method are now deprecated,
+    as the reconnect feature was removed in PHP 8.2. (Kamil Tekiela)
+  . The mysqli_kill() function and mysqli::kill() method are now deprecated.
+    If this functionality is needed a SQL "KILL" command can be used instead.
+    (Kamil Tekiela)
+  . The mysqli_refresh() function and mysqli::refresh() method are now deprecated.
+    If this functionality is needed a SQL "FLUSH" command can be used instead.
+    (Kamil Tekiela)
+  . Passing explicitly the $mode parameter to mysqli_store_result() has been
+    deprecated. As the MYSQLI_STORE_RESULT_COPY_DATA constant was only used in
+    conjunction with this function it has also been deprecated. (Girgias)
+
+- MySQLnd:
+  . Fixed bug GH-13440 (PDO quote bottleneck). (nielsdos)
+  . Fixed bug GH-10599 (Apache crash on Windows when using a self-referencing
+    anonymous function inside a class with an active mysqli connection).
+    (nielsdos)
+
+- Opcache:
+  . Added large shared segments support for FreeBSD. (David Carlier)
+  . If JIT is enabled, PHP will now exit with a fatal error on startup in case
+    of JIT startup initialization issues. (danog)
+  . Increased the maximum value of opcache.interned_strings_buffer to 32767 on
+    64bit archs. (Arnaud)
+  . Fixed bug GH-13834 (Applying non-zero offset 36 to null pointer in
+    zend_jit.c). (nielsdos)
+  . Fixed bug GH-14361 (Deep recursion in zend_cfg.c causes segfault).
+    (nielsdos)
+  . Fixed bug GH-14873 (PHP 8.4 min function fails on typed integer).
+    (nielsdos)
+  . Fixed bug GH-15490 (Building of callgraph modifies preloaded symbols).
+    (ilutov)
+  . Fixed bug GH-15178 (Assertion in tracing JIT on hooks). (ilutov)
+  . Fixed bug GH-15657 (Segmentation fault in dasm_x86.h). (nielsdos)
+  . Added opcache_jit_blacklist() function. (Bob)
+  . Fixed bug GH-16009 (Segmentation fault with frameless functions and
+    undefined CVs). (nielsdos)
+  . Fixed bug GH-16186 (Assertion failure in Zend/zend_operators.c). (Arnaud)
+  . Fixed bug GH-16572 (Incorrect result with reflection in low-trigger JIT).
+    (nielsdos)
+  . Fixed GH-16839 (Error on building Opcache JIT for Windows ARM64). (cmb)
+
+- OpenSSL:
+  . Fixed bug #80269 (OpenSSL sets Subject wrong with extraattribs parameter).
+    (Jakub Zelenka)
+  . Implement request #48520 (openssl_csr_new - allow multiple values in DN).
+    (Jakub Zelenka)
+  . Introduced new serial_hex parameter to openssl_csr_sign. (Jakub Zelenka,
+    Florian Sowade)
+  . Added X509_PURPOSE_OCSP_HELPER and X509_PURPOSE_TIMESTAMP_SIGN constants.
+    (Vincent Jardin)
+  . Bumped minimum required OpenSSL version to 1.1.1. (Ayesh Karunaratne)
+  . Added compile-time option --with-openssl-legacy-provider to enable legacy
+    provider. (Adam Saponara)
+  . Added support for Curve25519 + Curve448 based keys. (Manuel Mausz)
+  . Fixed bug GH-13343 (openssl_x509_parse should not allow omitted seconds in
+    UTCTimes). (Jakub Zelenka)
+  . Bumped minimum required OpenSSL version to 1.1.0. (cmb)
+  . Implement GH-13514 PASSWORD_ARGON2 from OpenSSL 3.2. (Remi)
+
+- Output:
+  . Clear output handler status flags during handler initialization. (haszi)
+  . Fixed bug with url_rewriter.hosts not used by output_add_rewrite_var().
+    (haszi)
+
+- PCNTL:
+  . Added pcntl_setns for Linux. (David Carlier)
+  . Added pcntl_getcpuaffinity/pcntl_setcpuaffinity. (David Carlier)
+  . Updated pcntl_get_signal_handler signal id upper limit to be
+    more in line with platforms limits. (David Carlier)
+  . Added pcntl_getcpu for Linux/FreeBSD/Solaris/Illumos. (David Carlier)
+  . Added pcntl_getqos_class/pcntl_setqos_class for macOs. (David Carlier)
+  . Added SIGCKPT/SIGCKPTEXIT constants for DragonFlyBSD. (David Carlier)
+  . Added FreeBSD's SIGTRAP handling to pcntl_siginfo_to_zval. (David Carlier)
+  . Added POSIX pcntl_waitid. (Vladimir Vrzić)
+  . Fixed bug GH-16769: (pcntl_sigwaitinfo aborts on signal value
+    as reference). (David Carlier)
+
+- PCRE:
+  . Upgrade bundled pcre2lib to version 10.43. (nielsdos)
+  . Add "/r" modifier. (Ayesh)
+  . Upgrade bundled pcre2lib to version 10.44. (Ayesh)
+  . Fixed GH-16189 (underflow on offset argument). (David Carlier)
+  . Fix UAF issues with PCRE after request shutdown. (nielsdos)
+
+- PDO:
+  . Fixed setAttribute and getAttribute. (SakiTakamachi)
+  . Implemented PDO driver-specific subclasses RFC. (danack, kocsismate)
+  . Added support for PDO driver-specific SQL parsers. (Matteo Beccati)
+  . Fixed bug GH-14792 (Compilation failure on pdo_* extensions).
+    (Peter Kokot)
+  . mysqlnd: support ER_CLIENT_INTERACTION_TIMEOUT. (Appla)
+  . The internal header php_pdo_int.h is no longer installed; it is not
+    supposed to be used by PDO drivers. (cmb)
+  . Fixed bug GH-16167 (Prevent mixing PDO sub-classes with different DSN).
+    (kocsismate)
+  . Fixed bug GH-16314 ("Pdo\Mysql object is uninitialized" when opening a
+    persistent connection). (kocsismate)
+
+- PDO_DBLIB:
+  . Fixed setAttribute and getAttribute. (SakiTakamachi)
+  . Added class Pdo\DbLib. (danack, kocsismate)
+
+- PDO_Firebird:
+  . Fixed setAttribute and getAttribute. (SakiTakamachi)
+  . Feature: Add transaction isolation level and mode settings to pdo_firebird.
+    (SakiTakamachi)
+  . Added class Pdo\Firebird. (danack, kocsismate)
+  . Added Pdo\Firebird::ATTR_API_VERSION. (SakiTakamachi)
+  . Added getApiVersion() and removed from getAttribute().
+    (SakiTakamachi)
+  . Supported Firebird 4.0 datatypes. (sim1984)
+  . Support proper formatting of time zone types. (sim1984)
+  . Fixed GH-15604 (Always make input parameters nullable). (sim1984)
+
+- PDO_MYSQL:
+  . Fixed setAttribute and getAttribute. (SakiTakamachi)
+  . Added class Pdo\Mysql. (danack, kocsismate)
+  . Added custom SQL parser. (Matteo Beccati)
+  . Fixed GH-15949 (PDO_MySQL not properly quoting PDO_PARAM_LOB binary
+    data). (mbeccati, lcobucci)
+
+- PDO_ODBC:
+  . Added class Pdo\Odbc. (danack, kocsismate)
+
+- PDO_PGSQL:
+  . Fixed GH-12423, DSN credentials being prioritized over the user/password
+    PDO constructor arguments. (SakiTakamachi)
+  . Fixed native float support with pdo_pgsql query results. (Yurunsoft)
+  . Added class Pdo\Pgsql. (danack, kocsismate)
+  . Retrieve the memory usage of the query result resource. (KentarouTakeda)
+  . Added Pdo\Pgsql::setNoticeCallBack method to receive DB notices.
+    (outtersg)
+  . Added custom SQL parser. (Matteo Beccati)
+  . Fixed GH-15986 (Double-free due to Pdo\Pgsql::setNoticeCallback()). (cmb,
+    nielsdos)
+  . Fixed GH-12940 (Using PQclosePrepared when available instead of
+    the DEALLOCATE command to free statements resources). (David Carlier)
+  . Remove PGSQL_ATTR_RESULT_MEMORY_SIZE constant as it is provided by
+    the new PDO Subclass as Pdo\Pgsql::ATTR_RESULT_MEMORY_SIZE. (Girgias)
+
+- PDO_SQLITE:
+  . Added class Pdo\Sqlite. (danack, kocsismate)
+  . Fixed bug #81227 (PDO::inTransaction reports false when in transaction).
+    (nielsdos)
+  . Added custom SQL parser. (Matteo Beccati)
+
+- PHPDBG:
+  . array out of bounds, stack overflow handled for segfault handler on windows.
+    (David Carlier)
+  . Fixed bug GH-16041 (Support stack limit in phpdbg). (Arnaud)
+
+- PGSQL:
+  . Added the possibility to have no conditions for pg_select. (OmarEmaraDev)
+  . Persistent connections support the PGSQL_CONNECT_FORCE_RENEW flag.
+    (David Carlier)
+  . Added pg_result_memory_size to get the query result memory usage.
+    (KentarouTakeda)
+  . Added pg_change_password to alter an user's password. (David Carlier)
+  . Added pg_put_copy_data/pg_put_copy_end to send COPY commands and signal
+    the end of the COPY. (David Carlier)
+  . Added pg_socket_poll to poll on the connection. (David Carlier)
+  . Added pg_jit to get infos on server JIT support. (David Carlier)
+  . Added pg_set_chunked_rows_size to fetch results per chunk. (David Carlier)
+  . pg_convert/pg_insert/pg_update/pg_delete ; regexes are now cached.
+    (David Carlier)
+
+- Phar:
+  . Fixed bug GH-12532 (PharData created from zip has incorrect timestamp).
+    (nielsdos)
+
+- POSIX:
+  . Added POSIX_SC_CHILD_MAX and POSIX_SC_CLK_TCK constants. (Jakub Zelenka)
+  . Updated posix_isatty to set the error number on file descriptors.
+    (David Carlier)
+
+- PSpell:
+  . Moved to PECL. (Derick Rethans)
+
+- Random:
+  . Fixed bug GH-15094 (php_random_default_engine() is not C++ conforming).
+    (cmb)
+  . lcg_value() is now deprecated. (timwolla)
+
+- Readline:
+  . Fixed readline_info, rl_line_buffer_length/rl_len globals on update.
+    (David Carlier)
+  . Fixed bug #51558 (Shared readline build fails). (Peter Kokot)
+  . Fixed UAF with readline_info(). (David Carlier)
+
+- Reflection:
+  . Implement GH-12908 (Show attribute name/class in ReflectionAttribute dump).
+    (nielsdos)
+  . Make ReflectionGenerator::getFunction() legal after generator termination.
+    (timwolla)
+  . Added ReflectionGenerator::isClosed(). (timwolla)
+  . Fixed bug GH-15718 (Segfault on ReflectionProperty::get{Hook,Hooks}() on
+    dynamic properties). (DanielEScherzer)
+  . Fixed bug GH-15694 (ReflectionProperty::isInitialized() is incorrect for
+    hooked properties). (ilutov)
+  . Add missing ReflectionProperty::hasHook[s]() methods. (ilutov)
+  . Add missing ReflectionProperty::isFinal() method. (ilutov)
+  . Fixed bug GH-16122 (The return value of ReflectionFunction::getNamespaceName()
+    and ReflectionFunction::inNamespace() for closures is incorrect). (timwolla)
+  . Fixed bug GH-16162 (No ReflectionProperty::IS_VIRTUAL) (DanielEScherzer)
+  . Fixed the name of the second parameter of
+    ReflectionClass::resetAsLazyGhost(). (Arnaud)
+
+- Session:
+  . INI settings session.sid_length and session.sid_bits_per_character are now
+    deprecated. (timwolla)
+  . Emit warnings for non-positive values of session.gc_divisor and negative values
+    of session.gc_probability. (Jorg Sowa)
+  . Fixed bug GH-16590 (UAF in session_encode()). (nielsdos)
+
+- SimpleXML:
+  . Fix signature of simplexml_import_dom(). (nielsdos)
+
+- SNMP:
+  . Removed the deprecated inet_ntoa call support. (David Carlier)
+
+- SOAP:
+  . Add support for clark notation for namespaces in class map. (lxShaDoWxl)
+  . Mitigate #51561 (SoapServer with a extented class and using sessions,
+    lost the setPersistence()). (nielsdos)
+  . Fixed bug #49278 (SoapClient::__getLastResponseHeaders returns NULL if
+    wsdl operation !has output). (nielsdos)
+  . Fixed bug #44383 (PHP DateTime not converted to xsd:datetime). (nielsdos)
+  . Fixed bug GH-11941 (soap with session persistence will silently fail when
+    "session" built as a shared object). (nielsdos)
+  . Passing an int to SoapServer::addFunction() is now deprecated.
+    If all PHP functions need to be provided flatten the array returned by
+    get_defined_functions(). (Girgias)
+  . The SOAP_FUNCTIONS_ALL constant is now deprecated. (Girgias)
+  . Fixed bug #61525 (SOAP functions require at least one space after HTTP
+    header colon). (nielsdos)
+  . Implement request #47317 (SoapServer::__getLastResponse()). (nielsdos)
+
+- Sockets:
+  . Removed the deprecated inet_ntoa call support. (David Carlier)
+  . Added the SO_EXECLUSIVEADDRUSE windows constant. (David Carlier)
+  . Added the SOCK_CONN_DGRAM/SOCK_DCCP netbsd constants. (David Carlier)
+  . Added multicast group support for ipv4 on FreeBSD. (jonathan@tangential.ca)
+  . Added the TCP_SYNCNT constant for Linux to set number of attempts to send
+    SYN packets from the client. (David Carlier)
+  . Added the SO_EXCLBIND constant for exclusive socket binding on illumos/solaris.
+    (David Carlier)
+  . Updated the socket_create_listen backlog argument default value to SOMAXCONN.
+    (David Carlier)
+  . Added the SO_NOSIGPIPE constant to control the generation of SIGPIPE for
+    macOs and FreeBSD. (David Carlier)
+  . Added SO_LINGER_SEC for macOs, true equivalent of SO_LINGER in other platforms.
+    (David Carlier)
+  . Add close-on-exec on socket created with socket_accept on unixes. (David Carlier)
+  . Added IP_PORTRANGE* constants for BSD systems to control ephemeral port
+    ranges. (David Carlier)
+  . Added SOCK_NONBLOCK/SOCK_CLOEXEC constants for socket_create and
+    socket_create_pair to apply O_NONBLOCK/O_CLOEXEC flags to the
+    newly created sockets. (David Carlier)
+  . Added SO_BINDTOIFINDEX to bind a socket to an interface index.
+    (David Carlier)
+
+- Sodium:
+  . Add support for AEGIS-128L and AEGIS-256. (jedisct1)
+  . Enable AES-GCM on aarch64 with the ARM crypto extensions. (jedisct1)
+
+- SPL:
+  . Implement SeekableIterator for SplObjectStorage. (nielsdos)
+  . The SplFixedArray::__wakeup() method has been deprecated as it implements
+    __serialize() and __unserialize() which need to be overwritten instead.
+    (TysonAndre)
+  . Passing a non-empty string for the $escape parameter of:
+    - SplFileObject::setCsvControl()
+    - SplFileObject::fputcsv()
+    - SplFileObject::fgetcsv()
+    is now deprecated. (Girgias)
+
+- Standard:
+  . Implement GH-12188 (Indication for the int size in phpinfo()). (timwolla)
+  . Partly fix GH-12143 (Incorrect round() result for 0.49999999999999994).
+    (timwolla)
+  . Fix GH-12252 (round(): Validate the rounding mode). (timwolla)
+  . Increase the default BCrypt cost to 12. (timwolla)
+  . Fixed bug GH-12592 (strcspn() odd behaviour with NUL bytes and empty mask).
+    (nielsdos)
+  . Removed the deprecated inet_ntoa call support. (David Carlier)
+  . Cast large floats that are within int range to int in number_format so
+    the precision is not lost. (Marc Bennewitz)
+  . Add support for 4 new rounding modes to the round() function. (Jorg Sowa)
+  . debug_zval_dump() now indicates whether an array is packed. (Max Semenik)
+  . Fix GH-12143 (Optimize round). (SakiTakamachi)
+  . Changed return type of long2ip to string from string|false. (Jorg Sowa)
+  . Fix GH-12143 (Extend the maximum precision round can handle by one digit).
+    (SakiTakamachi)
+  . Added the http_get_last_response_headers() and
+    http_clear_last_response_headers() that allows retrieving the same content
+    as the magic $http_response_header variable.
+  . Add php_base64_encode_ex() API. (Remi)
+  . Implemented "Raising zero to the power of negative number" RFC. (Jorg Sowa)
+  . Added array_find(), array_find_key(), array_all(), and array_any(). (josh)
+  . Change highlight_string() and print_r() return type to string|true. (Ayesh)
+  . Fix references in request_parse_body() options array. (nielsdos)
+  . Add RoundingMode enum. (timwolla, saki)
+  . Unserializing the uppercase 'S' tag is now deprecated. (timwolla)
+  . Enables crc32 auxiliary detection on OpenBSD. (David Carlier)
+  . Passing a non-empty string for the $escape parameter of:
+    - fputcsv()
+    - fgetcsv()
+    - str_getcsv()
+    is now deprecated. (Girgias)
+  . The str_getcsv() function now throws ValueErrors when the $separator and
+    $enclosure arguments are not one byte long, or if the $escape is not one
+    byte long or the empty string. This aligns the behaviour to be identical
+    to that of fputcsv() and fgetcsv(). (Girgias)
+  . php_uname() now throws ValueErrors on invalid inputs. (Girgias)
+  . The "allowed_classes" option for unserialize() now throws TypeErrors and
+    ValueErrors	if it is not an	array of class names. (Girgias)
+  . Implemented GH-15685 (improve proc_open error reporting on Windows). (cmb)
+  . Add support for backed enums in http_build_query(). (ilutov)
+  . Fixed bug GH-15982 (Assertion failure with array_find when references are
+    involved). (nielsdos)
+  . Fixed parameter names of fpow() to be identical to pow(). (Girgias)
+
+- Streams:
+  . Implemented GH-15155 (Stream context is lost when custom stream wrapper is
+    being filtered). (Quentin Dreyer)
+
+- Tidy:
+  . Failures in the constructor now throw exceptions rather than emitting
+    warnings and having a broken object. (nielsdos)
+  . Add tidyNode::getNextSibling() and tidyNode::getPreviousSibling().
+    (nielsdos)
+
+- Windows:
+  . Update the icon of the Windows executables, e.g. php.exe. (Ayesh,
+    Nurudin Imširović)
+  . Fixed bug GH-16199 (GREP_HEADER() is broken). (Peter Kokot)
+
+- XML:
+  . Added XML_OPTION_PARSE_HUGE parser option. (nielsdos)
+  . Fixed bug #81481 (xml_get_current_byte_index limited to 32-bit numbers on
+    64-bit builds). (nielsdos)
+  . The xml_set_object() function has been deprecated. (Girgias)
+  . Passing non-callable strings to the xml_set_*_handler() functions is now
+    deprecated. (Girgias)
+
+- XMLReader:
+  . Declares class constant types. (Ayesh)
+  . Add XMLReader::fromStream(), XMLReader::fromUri(), XMLReader::fromString(). (nielsdos)
+  . Fixed bug GH-15123 (var_dump doesn't actually work on XMLReader).
+    (nielsdos)
+
+- XMLWriter:
+  . Add XMLWriter::toStream(), XMLWriter::toUri(), XMLWriter::toMemory(). (nielsdos)
+
+- XSL:
+  . Implement request #64137 (XSLTProcessor::setParameter() should allow both
+    quotes to be used). (nielsdos)
+  . Implemented "Improve callbacks in ext/dom and ext/xsl" RFC. (nielsdos)
+  . Added XSLTProcessor::$maxTemplateDepth and XSLTProcessor::$maxTemplateVars.
+    (nielsdos)
+  . Fix trampoline leak in xpath callables. (nielsdos)
+
+- Zip:
+  . Added ZipArchive::ER_TRUNCATED_ZIP added in libzip 1.11. (Remi)
diff '--color=auto' -Naur a/Zend/tests/gh19844.phpt b/Zend/tests/gh19844.phpt
--- a/Zend/tests/gh19844.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/Zend/tests/gh19844.phpt	2025-11-18 21:43:27.124632087 +0000
@@ -0,0 +1,46 @@
+--TEST--
+GH-19844: Bail from stream_close() in zend_shutdown_executor_values()
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == 'WIN') die('skip Aborts with STATUS_BAD_FUNCTION_TABLE on Windows');
+?>
+--FILE--
+<?php
+
+class Test {
+    public $context;
+    private static $nested = false;
+
+    function stream_open() {
+        return true;
+    }
+
+    function stream_read() {
+        return '.';
+    }
+    function stream_set_option() {}
+    function stream_stat() {}
+
+    function stream_eof() {
+        if (!Test::$nested) {
+            Test::$nested = true;
+            include 'Test://';
+        }
+        @trigger_error('Bail', E_USER_ERROR);
+    }
+
+    function stream_close() {
+        @trigger_error('Bail', E_USER_ERROR);
+    }
+}
+
+stream_wrapper_register('Test', Test::class);
+include 'Test://';
+
+?>
+--EXPECTF--
+Fatal error: Bail in %s on line %d
+
+Fatal error: Bail in %s on line %d
+
+Fatal error: Bail in %s on line %d
diff '--color=auto' -Naur a/Zend/tests/gh20177.phpt b/Zend/tests/gh20177.phpt
--- a/Zend/tests/gh20177.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/Zend/tests/gh20177.phpt	2025-11-18 21:43:27.124918097 +0000
@@ -0,0 +1,25 @@
+--TEST--
+GH-20177: Access overridden private property in get_object_vars()
+--FILE--
+<?php
+
+class A {
+    private $prop = 'A::$prop';
+
+    public function __construct() {
+        var_dump(get_object_vars($this));
+    }
+}
+
+class B extends A {
+    protected $prop = 'B::$prop';
+}
+
+new B;
+
+?>
+--EXPECT--
+array(1) {
+  ["prop"]=>
+  string(8) "A::$prop"
+}
diff '--color=auto' -Naur a/Zend/tests/gh20183_001.phpt b/Zend/tests/gh20183_001.phpt
--- a/Zend/tests/gh20183_001.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/Zend/tests/gh20183_001.phpt	2025-11-18 21:43:27.125052170 +0000
@@ -0,0 +1,24 @@
+--TEST--
+GH-20183: Stale EG(opline_before_exception) pointer through eval
+--CREDITS--
+Viet Hoang Luu (@vi3tL0u1s)
+--FILE--
+<?php
+
+class A {
+    function __destruct() {
+        eval('try { throw new Error(); } catch (Error $e) {}');
+        debug_print_backtrace();
+    }
+}
+
+B::$b = new A;
+
+?>
+--EXPECTF--
+#0 %s(10): A->__destruct()
+
+Fatal error: Uncaught Error: Class "B" not found in %s:10
+Stack trace:
+#0 {main}
+  thrown in %s on line 10
diff '--color=auto' -Naur a/Zend/tests/gh20183_002.phpt b/Zend/tests/gh20183_002.phpt
--- a/Zend/tests/gh20183_002.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/Zend/tests/gh20183_002.phpt	2025-11-18 21:43:27.125168259 +0000
@@ -0,0 +1,34 @@
+--TEST--
+GH-20183: Stale EG(opline_before_exception) pointer through eval
+--CREDITS--
+Arnaud Le Blanc <lbarnaud@php.net>
+--FILE--
+<?php
+
+function gen() {
+    try {
+        yield 1;
+    } finally {
+        eval('try { throw new Error(); } catch (Error) {}');
+        debug_print_backtrace();
+    }
+}
+
+class A {
+    private $gen;
+    function __construct() {
+        $this->gen = gen();
+        $this->gen->rewind();
+    }
+}
+
+B::$a = new A();
+
+?>
+--EXPECTF--
+#0 %s(20): gen()
+
+Fatal error: Uncaught Error: Class "B" not found in %s:20
+Stack trace:
+#0 {main}
+  thrown in %s on line 20
diff '--color=auto' -Naur a/Zend/tests/lazy_objects/gh20085.phpt b/Zend/tests/lazy_objects/gh20085.phpt
--- a/Zend/tests/lazy_objects/gh20085.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/Zend/tests/lazy_objects/gh20085.phpt	2025-11-18 21:43:27.125201552 +0000
@@ -0,0 +1,25 @@
+--TEST--
+GH-20085 (Assertion failure when combining lazy object get_properties exception with foreach loop)
+--FILE--
+<?php
+class C {
+    public int $a;
+    public function __construct() {
+        $this->a = 1;
+    }
+}
+$obj = new C;
+$reflector = new ReflectionClass(C::class);
+foreach ($obj as &$value) {
+    $obj = $reflector->newLazyGhost(function ($obj) {
+        throw new Error;
+    });
+}
+echo !obj;
+?>
+--EXPECTF--
+Fatal error: Uncaught Error in %s:%d
+Stack trace:
+#0 %s(%d): {closure:%s:%d}(Object(C))
+#1 {main}
+  thrown in %s on line %d
diff '--color=auto' -Naur a/Zend/tests/oss_fuzz_456317305.phpt b/Zend/tests/oss_fuzz_456317305.phpt
--- a/Zend/tests/oss_fuzz_456317305.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/Zend/tests/oss_fuzz_456317305.phpt	2025-11-18 21:43:27.125353990 +0000
@@ -0,0 +1,25 @@
+--TEST--
+OSS-Fuzz #456317305: EG(current_execute_data) NULL pointer violation
+--FILE--
+<?php
+
+class C {
+    public function __destruct() {
+        static $again = true;
+        if ($again) {
+            $again = false;
+            $c = new C;
+        }
+        throw new Exception;
+    }
+}
+
+$c = new C;
+
+?>
+--EXPECTF--
+Fatal error: Uncaught Exception in %s:%d
+Stack trace:
+#0 [internal function]: C->__destruct()
+#1 {main}
+  thrown in %s on line %d
diff '--color=auto' -Naur a/Zend/tests/property_hooks/gh20270.phpt b/Zend/tests/property_hooks/gh20270.phpt
--- a/Zend/tests/property_hooks/gh20270.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/Zend/tests/property_hooks/gh20270.phpt	2025-11-18 21:43:27.125450673 +0000
@@ -0,0 +1,51 @@
+--TEST--
+GH-20270: Parent hook call with named arguments
+--CREDITS--
+Viet Hoang Luu (@vi3tL0u1s)
+--FILE--
+<?php
+
+class A {
+    public mixed $prop1;
+    public mixed $prop2 {
+        set(mixed $custom) => $custom;
+    }
+}
+
+class B extends A {
+    public mixed $prop1 {
+        set {
+            parent::$prop1::set(value: 42);
+            parent::$prop1::set(unknown: 43);
+        }
+    }
+    public mixed $prop2 {
+        set {
+            parent::$prop2::set(custom: 42);
+            parent::$prop2::set(value: 43);
+        }
+    }
+}
+
+$b = new B();
+
+try {
+    $b->prop1 = 0;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+var_dump($b->prop1);
+
+try {
+    $b->prop2 = 0;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+var_dump($b->prop2);
+
+?>
+--EXPECT--
+Unknown named parameter $unknown
+int(42)
+Unknown named parameter $value
+int(42)
diff '--color=auto' -Naur a/Zend/tests/weakrefs/gh20073.phpt b/Zend/tests/weakrefs/gh20073.phpt
--- a/Zend/tests/weakrefs/gh20073.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/Zend/tests/weakrefs/gh20073.phpt	2025-11-18 21:43:27.125593953 +0000
@@ -0,0 +1,15 @@
+--TEST--
+GH-20073 (Assertion failure in WeakMap offset operations on reference)
+--FILE--
+<?php
+$obj = new stdClass;
+$map = new WeakMap;
+$integer = 1;
+$map[$obj] = 0;
+$map[$obj] =& $integer;
+$integer++;
+var_dump($map[$obj], $map->offsetGet($obj));
+?>
+--EXPECT--
+int(2)
+int(2)
diff '--color=auto' -Naur a/Zend/zend.h b/Zend/zend.h
--- a/Zend/zend.h	2025-10-21 19:23:55.000000000 +0000
+++ b/Zend/zend.h	2025-11-18 21:46:37.160014024 +0000
@@ -20,7 +20,7 @@
 #ifndef ZEND_H
 #define ZEND_H
 
-#define ZEND_VERSION "4.4.14"
+#define ZEND_VERSION "4.4.15"
 
 #define ZEND_ENGINE_3
 
diff '--color=auto' -Naur a/Zend/zend.h.orig b/Zend/zend.h.orig
--- a/Zend/zend.h.orig	1970-01-01 00:00:00.000000000 +0000
+++ b/Zend/zend.h.orig	2025-11-18 21:42:37.757098009 +0000
@@ -0,0 +1,456 @@
+/*
+   +----------------------------------------------------------------------+
+   | Zend Engine                                                          |
+   +----------------------------------------------------------------------+
+   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.00 of the Zend license,     |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.zend.com/license/2_00.txt.                                |
+   | If you did not receive a copy of the Zend license and are unable to  |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@zend.com so we can mail you a copy immediately.              |
+   +----------------------------------------------------------------------+
+   | Authors: Andi Gutmans <andi@php.net>                                 |
+   |          Zeev Suraski <zeev@php.net>                                 |
+   +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_H
+#define ZEND_H
+
+#define ZEND_VERSION "4.4.14"
+
+#define ZEND_ENGINE_3
+
+#include "zend_types.h"
+#include "zend_map_ptr.h"
+#include "zend_errors.h"
+#include "zend_alloc.h"
+#include "zend_llist.h"
+#include "zend_string.h"
+#include "zend_hash.h"
+#include "zend_ast.h"
+#include "zend_gc.h"
+#include "zend_variables.h"
+#include "zend_iterators.h"
+#include "zend_stream.h"
+#include "zend_smart_str_public.h"
+#include "zend_smart_string_public.h"
+#include "zend_signal.h"
+#include "zend_max_execution_timer.h"
+
+#define zend_sprintf sprintf
+
+#define HANDLE_BLOCK_INTERRUPTIONS()		ZEND_SIGNAL_BLOCK_INTERRUPTIONS()
+#define HANDLE_UNBLOCK_INTERRUPTIONS()		ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS()
+
+#define INTERNAL_FUNCTION_PARAMETERS zend_execute_data *execute_data, zval *return_value
+#define INTERNAL_FUNCTION_PARAM_PASSTHRU execute_data, return_value
+
+#define USED_RET() \
+	(!EX(prev_execute_data) || \
+	 !ZEND_USER_CODE(EX(prev_execute_data)->func->common.type) || \
+	 (EX(prev_execute_data)->opline->result_type != IS_UNUSED))
+
+#ifdef ZEND_ENABLE_STATIC_TSRMLS_CACHE
+#define ZEND_TSRMG TSRMG_STATIC
+#define ZEND_TSRMG_FAST TSRMG_FAST_STATIC
+#define ZEND_TSRMLS_CACHE_EXTERN() TSRMLS_CACHE_EXTERN()
+#define ZEND_TSRMLS_CACHE_DEFINE() TSRMLS_CACHE_DEFINE()
+#define ZEND_TSRMLS_CACHE_UPDATE() TSRMLS_CACHE_UPDATE()
+#define ZEND_TSRMLS_CACHE TSRMLS_CACHE
+#else
+#define ZEND_TSRMG TSRMG
+#define ZEND_TSRMG_FAST TSRMG_FAST
+#define ZEND_TSRMLS_CACHE_EXTERN()
+#define ZEND_TSRMLS_CACHE_DEFINE()
+#define ZEND_TSRMLS_CACHE_UPDATE()
+#define ZEND_TSRMLS_CACHE
+#endif
+
+#ifndef ZEND_COMPILE_DL_EXT
+TSRMLS_MAIN_CACHE_EXTERN()
+#else
+ZEND_TSRMLS_CACHE_EXTERN()
+#endif
+
+struct _zend_serialize_data;
+struct _zend_unserialize_data;
+
+typedef struct _zend_serialize_data zend_serialize_data;
+typedef struct _zend_unserialize_data zend_unserialize_data;
+
+typedef struct _zend_class_name {
+	zend_string *name;
+	zend_string *lc_name;
+} zend_class_name;
+
+typedef struct _zend_trait_method_reference {
+	zend_string *method_name;
+	zend_string *class_name;
+} zend_trait_method_reference;
+
+typedef struct _zend_trait_precedence {
+	zend_trait_method_reference trait_method;
+	uint32_t num_excludes;
+	zend_string *exclude_class_names[1];
+} zend_trait_precedence;
+
+typedef struct _zend_trait_alias {
+	zend_trait_method_reference trait_method;
+
+	/**
+	* name for method to be added
+	*/
+	zend_string *alias;
+
+	/**
+	* modifiers to be set on trait method
+	*/
+	uint32_t modifiers;
+} zend_trait_alias;
+
+typedef struct _zend_class_mutable_data {
+	zval      *default_properties_table;
+	HashTable *constants_table;
+	uint32_t   ce_flags;
+	HashTable *backed_enum_table;
+} zend_class_mutable_data;
+
+typedef struct _zend_class_dependency {
+	zend_string      *name;
+	zend_class_entry *ce;
+} zend_class_dependency;
+
+typedef struct _zend_inheritance_cache_entry zend_inheritance_cache_entry;
+
+typedef struct _zend_error_info {
+	int type;
+	uint32_t lineno;
+	zend_string *filename;
+	zend_string *message;
+} zend_error_info;
+
+struct _zend_inheritance_cache_entry {
+	zend_inheritance_cache_entry *next;
+	zend_class_entry             *ce;
+	zend_class_entry             *parent;
+	zend_class_dependency        *dependencies;
+	uint32_t                      dependencies_count;
+	uint32_t                      num_warnings;
+	zend_error_info             **warnings;
+	zend_class_entry             *traits_and_interfaces[1];
+};
+
+struct _zend_class_entry {
+	char type;
+	zend_string *name;
+	/* class_entry or string depending on ZEND_ACC_LINKED */
+	union {
+		zend_class_entry *parent;
+		zend_string *parent_name;
+	};
+	int refcount;
+	uint32_t ce_flags;
+
+	int default_properties_count;
+	int default_static_members_count;
+	zval *default_properties_table;
+	zval *default_static_members_table;
+	ZEND_MAP_PTR_DEF(zval *, static_members_table);
+	HashTable function_table;
+	HashTable properties_info;
+	HashTable constants_table;
+
+	ZEND_MAP_PTR_DEF(zend_class_mutable_data*, mutable_data);
+	zend_inheritance_cache_entry *inheritance_cache;
+
+	struct _zend_property_info **properties_info_table;
+
+	zend_function *constructor;
+	zend_function *destructor;
+	zend_function *clone;
+	zend_function *__get;
+	zend_function *__set;
+	zend_function *__unset;
+	zend_function *__isset;
+	zend_function *__call;
+	zend_function *__callstatic;
+	zend_function *__tostring;
+	zend_function *__debugInfo;
+	zend_function *__serialize;
+	zend_function *__unserialize;
+
+	const zend_object_handlers *default_object_handlers;
+
+	/* allocated only if class implements Iterator or IteratorAggregate interface */
+	zend_class_iterator_funcs *iterator_funcs_ptr;
+	/* allocated only if class implements ArrayAccess interface */
+	zend_class_arrayaccess_funcs *arrayaccess_funcs_ptr;
+
+	/* handlers */
+	union {
+		zend_object* (*create_object)(zend_class_entry *class_type);
+		int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type); /* a class implements this interface */
+	};
+	zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref);
+	zend_function *(*get_static_method)(zend_class_entry *ce, zend_string* method);
+
+	/* serializer callbacks */
+	int (*serialize)(zval *object, unsigned char **buffer, size_t *buf_len, zend_serialize_data *data);
+	int (*unserialize)(zval *object, zend_class_entry *ce, const unsigned char *buf, size_t buf_len, zend_unserialize_data *data);
+
+	uint32_t num_interfaces;
+	uint32_t num_traits;
+	uint32_t num_hooked_props;
+	uint32_t num_hooked_prop_variance_checks;
+
+	/* class_entry or string(s) depending on ZEND_ACC_LINKED */
+	union {
+		zend_class_entry **interfaces;
+		zend_class_name *interface_names;
+	};
+
+	zend_class_name *trait_names;
+	zend_trait_alias **trait_aliases;
+	zend_trait_precedence **trait_precedences;
+	HashTable *attributes;
+
+	uint32_t enum_backing_type;
+	HashTable *backed_enum_table;
+
+	zend_string *doc_comment;
+
+	union {
+		struct {
+			zend_string *filename;
+			uint32_t line_start;
+			uint32_t line_end;
+		} user;
+		struct {
+			const struct _zend_function_entry *builtin_functions;
+			struct _zend_module_entry *module;
+		} internal;
+	} info;
+};
+
+typedef union {
+	zend_max_align_t align;
+	uint64_t opaque[5];
+} zend_random_bytes_insecure_state;
+
+typedef struct _zend_utility_functions {
+	void (*error_function)(int type, zend_string *error_filename, const uint32_t error_lineno, zend_string *message);
+	size_t (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
+	size_t (*write_function)(const char *str, size_t str_length);
+	FILE *(*fopen_function)(zend_string *filename, zend_string **opened_path);
+	void (*message_handler)(zend_long message, const void *data);
+	zval *(*get_configuration_directive)(zend_string *name);
+	void (*ticks_function)(int ticks);
+	void (*on_timeout)(int seconds);
+	zend_result (*stream_open_function)(zend_file_handle *handle);
+	void (*printf_to_smart_string_function)(smart_string *buf, const char *format, va_list ap);
+	void (*printf_to_smart_str_function)(smart_str *buf, const char *format, va_list ap);
+	char *(*getenv_function)(const char *name, size_t name_len);
+	zend_string *(*resolve_path_function)(zend_string *filename);
+	zend_result (*random_bytes_function)(void *bytes, size_t size, char *errstr, size_t errstr_size);
+	void (*random_bytes_insecure_function)(zend_random_bytes_insecure_state *state, void *bytes, size_t size);
+} zend_utility_functions;
+
+typedef struct _zend_utility_values {
+	bool html_errors;
+} zend_utility_values;
+
+typedef size_t (*zend_write_func_t)(const char *str, size_t str_length);
+
+#define zend_bailout()		_zend_bailout(__FILE__, __LINE__)
+
+#define zend_try												\
+	{															\
+		JMP_BUF *__orig_bailout = EG(bailout);					\
+		JMP_BUF __bailout;										\
+																\
+		EG(bailout) = &__bailout;								\
+		if (SETJMP(__bailout)==0) {
+#define zend_catch												\
+		} else {												\
+			EG(bailout) = __orig_bailout;
+#define zend_end_try()											\
+		}														\
+		EG(bailout) = __orig_bailout;							\
+	}
+#define zend_first_try		EG(bailout)=NULL;	zend_try
+
+BEGIN_EXTERN_C()
+void zend_startup(zend_utility_functions *utility_functions);
+void zend_shutdown(void);
+void zend_register_standard_ini_entries(void);
+zend_result zend_post_startup(void);
+void zend_set_utility_values(zend_utility_values *utility_values);
+void zend_unload_modules(void);
+
+ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32_t lineno);
+ZEND_API size_t zend_get_page_size(void);
+
+ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap);
+ZEND_API size_t zend_spprintf(char **message, size_t max_len, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 3, 4);
+ZEND_API zend_string *zend_vstrpprintf(size_t max_len, const char *format, va_list ap);
+ZEND_API zend_string *zend_strpprintf(size_t max_len, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
+
+/* Same as zend_spprintf and zend_strpprintf, without checking of format validity.
+ * For use with custom printf specifiers such as %H. */
+ZEND_API size_t zend_spprintf_unchecked(char **message, size_t max_len, const char *format, ...);
+ZEND_API zend_string *zend_strpprintf_unchecked(size_t max_len, const char *format, ...);
+
+ZEND_API const char *get_zend_version(void);
+ZEND_API bool zend_make_printable_zval(zval *expr, zval *expr_copy);
+ZEND_API size_t zend_print_zval(zval *expr, int indent);
+ZEND_API void zend_print_zval_r(zval *expr, int indent);
+ZEND_API zend_string *zend_print_zval_r_to_str(zval *expr, int indent);
+ZEND_API void zend_print_flat_zval_r(zval *expr);
+void zend_print_flat_zval_r_to_buf(smart_str *str, zval *expr);
+
+static zend_always_inline size_t zend_print_variable(zval *var) {
+	return zend_print_zval(var, 0);
+}
+
+ZEND_API ZEND_COLD void zend_output_debug_string(bool trigger_break, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
+
+ZEND_API void zend_activate(void);
+ZEND_API void zend_deactivate(void);
+ZEND_API void zend_call_destructors(void);
+ZEND_API void zend_activate_modules(void);
+ZEND_API void zend_deactivate_modules(void);
+ZEND_API void zend_post_deactivate_modules(void);
+
+ZEND_API void free_estring(char **str_p);
+
+END_EXTERN_C()
+
+/* output support */
+#define ZEND_WRITE(str, str_len)		zend_write((str), (str_len))
+#define ZEND_WRITE_EX(str, str_len)		write_func((str), (str_len))
+#define ZEND_PUTS(str)					zend_write((str), strlen((str)))
+#define ZEND_PUTS_EX(str)				write_func((str), strlen((str)))
+#define ZEND_PUTC(c)					zend_write(&(c), 1)
+
+BEGIN_EXTERN_C()
+extern ZEND_API size_t (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
+extern ZEND_API zend_write_func_t zend_write;
+extern ZEND_API FILE *(*zend_fopen)(zend_string *filename, zend_string **opened_path);
+extern ZEND_API void (*zend_ticks_function)(int ticks);
+
+/* Called by the VM in certain places like at the loop header, user function
+ * entry, and after internal function calls, if EG(vm_interrupt) has been set.
+ *
+ * If this is used to switch the EG(current_execute_data), such as implementing
+ * a coroutine scheduler, then it needs to check the top frame to see if it's
+ * an internal function. If an internal function is on top, then the frame
+ * shouldn't be switched away.
+ *
+ * Prior to PHP 8.0, this check was not necessary. In PHP 8.0,
+ * zend_call_function started calling zend_interrupt_function, and in 8.4 the
+ * DO_*CALL* opcodes started calling the zend_interrupt_function while the
+ * internal frame is still on top.
+ */
+extern ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data);
+
+extern ZEND_API void (*zend_error_cb)(int type, zend_string *error_filename, const uint32_t error_lineno, zend_string *message);
+extern ZEND_API void (*zend_on_timeout)(int seconds);
+extern ZEND_API zend_result (*zend_stream_open_function)(zend_file_handle *handle);
+extern void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap);
+extern void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap);
+extern ZEND_API char *(*zend_getenv)(const char *name, size_t name_len);
+extern ZEND_API zend_string *(*zend_resolve_path)(zend_string *filename);
+/* Generate 'size' random bytes into 'bytes' with the OS CSPRNG. */
+extern ZEND_ATTRIBUTE_NONNULL ZEND_API zend_result (*zend_random_bytes)(
+		void *bytes, size_t size, char *errstr, size_t errstr_size);
+/* Generate 'size' random bytes into 'bytes' with a general purpose PRNG (not
+ * crypto safe). 'state' must be zeroed before the first call and can be reused.
+ */
+extern ZEND_ATTRIBUTE_NONNULL ZEND_API void (*zend_random_bytes_insecure)(
+		zend_random_bytes_insecure_state *state, void *bytes, size_t size);
+
+/* These two callbacks are especially for opcache */
+extern ZEND_API zend_result (*zend_post_startup_cb)(void);
+extern ZEND_API void (*zend_post_shutdown_cb)(void);
+
+extern ZEND_API void (*zend_accel_schedule_restart_hook)(int reason);
+
+ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn_unchecked(int type, const char *format, ...);
+/* For custom format specifiers like H */
+ZEND_API ZEND_COLD void zend_error_unchecked(int type, const char *format, ...);
+/* If filename is NULL the default filename is used. */
+ZEND_API ZEND_COLD void zend_error_at(int type, zend_string *filename, uint32_t lineno, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 4, 5);
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn(int type, zend_string *filename, uint32_t lineno, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 4, 5);
+ZEND_API ZEND_COLD void zend_error_zstr(int type, zend_string *message);
+ZEND_API ZEND_COLD void zend_error_zstr_at(int type, zend_string *filename, uint32_t lineno, zend_string *message);
+
+ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
+ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
+ZEND_API ZEND_COLD void zend_argument_count_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
+ZEND_API ZEND_COLD void zend_value_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
+/* type should be one of the BP_VAR_* constants, only special messages happen for isset/empty and unset */
+ZEND_API ZEND_COLD void zend_illegal_container_offset(const zend_string *container, const zval *offset, int type);
+
+ZEND_COLD void zenderror(const char *error);
+
+/* For internal C errors */
+ZEND_API ZEND_COLD ZEND_NORETURN void zend_strerror_noreturn(int type, int errn, const char *message);
+
+/* The following #define is used for code duality in PHP for Engine 1 & 2 */
+#define ZEND_STANDARD_CLASS_DEF_PTR zend_standard_class_def
+extern ZEND_API zend_class_entry *zend_standard_class_def;
+extern ZEND_API zend_utility_values zend_uv;
+
+/* If DTrace is available and enabled */
+extern ZEND_API bool zend_dtrace_enabled;
+END_EXTERN_C()
+
+#define ZEND_UV(name) (zend_uv.name)
+
+BEGIN_EXTERN_C()
+ZEND_API void zend_message_dispatcher(zend_long message, const void *data);
+
+ZEND_API zval *zend_get_configuration_directive(zend_string *name);
+END_EXTERN_C()
+
+/* Messages for applications of Zend */
+#define ZMSG_FAILED_INCLUDE_FOPEN		1L
+#define ZMSG_FAILED_REQUIRE_FOPEN		2L
+#define ZMSG_FAILED_HIGHLIGHT_FOPEN		3L
+#define ZMSG_MEMORY_LEAK_DETECTED		4L
+#define ZMSG_MEMORY_LEAK_REPEATED		5L
+#define ZMSG_LOG_SCRIPT_NAME			6L
+#define ZMSG_MEMORY_LEAKS_GRAND_TOTAL	7L
+
+typedef enum {
+	EH_NORMAL = 0,
+	EH_THROW
+} zend_error_handling_t;
+
+typedef struct {
+	zend_error_handling_t  handling;
+	zend_class_entry       *exception;
+} zend_error_handling;
+
+BEGIN_EXTERN_C()
+ZEND_API void zend_save_error_handling(zend_error_handling *current);
+ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current);
+ZEND_API void zend_restore_error_handling(zend_error_handling *saved);
+ZEND_API void zend_begin_record_errors(void);
+ZEND_API void zend_emit_recorded_errors(void);
+ZEND_API void zend_free_recorded_errors(void);
+END_EXTERN_C()
+
+#define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0)
+#define DEBUG_BACKTRACE_IGNORE_ARGS    (1<<1)
+
+#include "zend_object_handlers.h"
+#include "zend_operators.h"
+
+#endif /* ZEND_H */
diff '--color=auto' -Naur a/Zend/zend_compile.c b/Zend/zend_compile.c
--- a/Zend/zend_compile.c	2025-10-21 19:23:55.000000000 +0000
+++ b/Zend/zend_compile.c	2025-11-18 21:43:27.127565400 +0000
@@ -2023,12 +2023,12 @@
 	zend_auto_global *auto_global;
 
 	ZEND_HASH_MAP_FOREACH_PTR(CG(auto_globals), auto_global) {
-		if (auto_global->jit) {
-			auto_global->armed = 1;
-		} else if (auto_global->auto_global_callback) {
+		auto_global->armed = auto_global->jit || auto_global->auto_global_callback;
+	} ZEND_HASH_FOREACH_END();
+
+	ZEND_HASH_MAP_FOREACH_PTR(CG(auto_globals), auto_global) {
+		if (auto_global->armed && !auto_global->jit) {
 			auto_global->armed = auto_global->auto_global_callback(auto_global->name);
-		} else {
-			auto_global->armed = 0;
 		}
 	} ZEND_HASH_FOREACH_END();
 }
diff '--color=auto' -Naur a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
--- a/Zend/zend_execute_API.c	2025-10-21 19:23:55.000000000 +0000
+++ b/Zend/zend_execute_API.c	2025-11-18 21:43:27.128565413 +0000
@@ -276,9 +276,7 @@
 	zval *zv;
 
 	EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN;
-	zend_try {
-		zend_close_rsrc_list(&EG(regular_list));
-	} zend_end_try();
+	zend_close_rsrc_list(&EG(regular_list));
 
 	/* No PHP callback functions should be called after this point. */
 	EG(active) = 0;
diff '--color=auto' -Naur a/Zend/zend_generators.c b/Zend/zend_generators.c
--- a/Zend/zend_generators.c	2025-10-21 19:23:55.000000000 +0000
+++ b/Zend/zend_generators.c	2025-11-18 21:43:27.129966478 +0000
@@ -309,9 +309,18 @@
 				ZEND_CALL_VAR(ex, ex->func->op_array.opcodes[try_catch->finally_end].op1.var);
 
 			zend_generator_cleanup_unfinished_execution(generator, ex, try_catch->finally_op);
-			zend_object *old_exception = EG(exception);
-			const zend_op *old_opline_before_exception = EG(opline_before_exception);
-			EG(exception) = NULL;
+
+			zend_object *old_exception = NULL;
+			const zend_op *old_opline_before_exception = NULL;
+			if (EG(exception)) {
+				if (EG(current_execute_data)) {
+					EG(current_execute_data)->opline = EG(opline_before_exception);
+					old_opline_before_exception = EG(opline_before_exception);
+				}
+				old_exception = EG(exception);
+				EG(exception) = NULL;
+			}
+
 			Z_OBJ_P(fast_call) = NULL;
 			Z_OPLINE_NUM_P(fast_call) = (uint32_t)-1;
 
@@ -321,7 +330,10 @@
 			zend_generator_resume(generator);
 
 			if (old_exception) {
-				EG(opline_before_exception) = old_opline_before_exception;
+				if (EG(current_execute_data)) {
+					EG(current_execute_data)->opline = EG(exception_op);
+					EG(opline_before_exception) = old_opline_before_exception;
+				}
 				if (EG(exception)) {
 					zend_exception_set_previous(EG(exception), old_exception);
 				} else {
diff '--color=auto' -Naur a/Zend/zend_list.c b/Zend/zend_list.c
--- a/Zend/zend_list.c	2025-10-21 19:23:55.000000000 +0000
+++ b/Zend/zend_list.c	2025-11-18 21:43:27.130613439 +0000
@@ -217,15 +217,25 @@
 	/* Reload ht->arData on each iteration, as it may be reallocated. */
 	uint32_t i = ht->nNumUsed;
 
-	while (i-- > 0) {
-		zval *p = ZEND_HASH_ELEMENT(ht, i);
-		if (Z_TYPE_P(p) != IS_UNDEF) {
-			zend_resource *res = Z_PTR_P(p);
-			if (res->type >= 0) {
-				zend_resource_dtor(res);
+retry:
+	zend_try {
+		while (i-- > 0) {
+			zval *p = ZEND_HASH_ELEMENT(ht, i);
+			if (Z_TYPE_P(p) != IS_UNDEF) {
+				zend_resource *res = Z_PTR_P(p);
+				if (res->type >= 0) {
+					zend_resource_dtor(res);
+				}
 			}
 		}
-	}
+	} zend_catch {
+		/* If we have bailed, we probably executed user code (e.g. user stream
+		 * API). Keep closing resources so they don't leak. User handlers must be
+		 * called now so they aren't called in zend_deactivate() on
+		 * zend_destroy_rsrc_list(&EG(regular_list)). At that point, the executor
+		 * has already shut down and the process would crash. */
+		goto retry;
+	} zend_end_try();
 }
 
 
diff '--color=auto' -Naur a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
--- a/Zend/zend_object_handlers.c	2025-10-21 19:23:55.000000000 +0000
+++ b/Zend/zend_object_handlers.c	2025-11-18 21:43:27.130970954 +0000
@@ -561,6 +561,11 @@
 				return FAILURE;
 			}
 		} else {
+			/* We were looking for a protected property but found a private one
+			 * belonging to the parent class. */
+			if (property_info->flags & ZEND_ACC_PRIVATE) {
+				return FAILURE;
+			}
 			ZEND_ASSERT(property_info->flags & ZEND_ACC_PROTECTED);
 		}
 		return SUCCESS;
@@ -1778,7 +1783,9 @@
 	const zend_property_info *prop_info,
 	zend_property_hook_kind kind, zend_string *prop_name)
 {
-	static const zend_arg_info arg_info[1] = {{0}};
+	static const zend_internal_arg_info arg_info[2] = {
+		{ .name = "value" }
+	};
 	zend_function *func;
 	if (EXPECTED(EG(trampoline).common.function_name == NULL)) {
 		func = &EG(trampoline);
diff '--color=auto' -Naur a/Zend/zend_objects.c b/Zend/zend_objects.c
--- a/Zend/zend_objects.c	2025-10-21 19:23:55.000000000 +0000
+++ b/Zend/zend_objects.c	2025-11-18 21:43:27.131913794 +0000
@@ -121,7 +121,7 @@
 		}
 
 		zend_object *old_exception;
-		const zend_op *old_opline_before_exception;
+		const zend_op *old_opline_before_exception = NULL;
 
 		if (destructor->op_array.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
 			if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
@@ -180,13 +180,15 @@
 			if (EG(exception) == object) {
 				zend_error_noreturn(E_CORE_ERROR, "Attempt to destruct pending exception");
 			} else {
-				if (EG(current_execute_data)
-				 && EG(current_execute_data)->func
-				 && ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
-					zend_rethrow_exception(EG(current_execute_data));
+				if (EG(current_execute_data)) {
+					if (EG(current_execute_data)->func
+					 && ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
+						zend_rethrow_exception(EG(current_execute_data));
+					}
+					EG(current_execute_data)->opline = EG(opline_before_exception);
+					old_opline_before_exception = EG(opline_before_exception);
 				}
 				old_exception = EG(exception);
-				old_opline_before_exception = EG(opline_before_exception);
 				EG(exception) = NULL;
 			}
 		}
@@ -194,7 +196,10 @@
 		zend_call_known_instance_method_with_0_params(destructor, object, NULL);
 
 		if (old_exception) {
-			EG(opline_before_exception) = old_opline_before_exception;
+			if (EG(current_execute_data)) {
+				EG(current_execute_data)->opline = EG(exception_op);
+				EG(opline_before_exception) = old_opline_before_exception;
+			}
 			if (EG(exception)) {
 				zend_exception_set_previous(EG(exception), old_exception);
 			} else {
diff '--color=auto' -Naur a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
--- a/Zend/zend_vm_def.h	2025-10-21 19:23:55.000000000 +0000
+++ b/Zend/zend_vm_def.h	2025-11-18 21:43:27.133565478 +0000
@@ -7275,7 +7275,7 @@
 			while (1) {
 				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
 					/* reached end of iteration */
-					ZEND_VM_C_GOTO(fe_fetch_w_exit);
+					ZEND_VM_C_GOTO(fe_fetch_w_exit_exc);
 				}
 				pos++;
 				value = &p->val;
@@ -7371,6 +7371,7 @@
 		}
 	} else {
 		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array));
+ZEND_VM_C_LABEL(fe_fetch_w_exit_exc):
 		if (UNEXPECTED(EG(exception))) {
 			UNDEF_RESULT();
 			HANDLE_EXCEPTION();
diff '--color=auto' -Naur a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
--- a/Zend/zend_vm_execute.h	2025-10-21 19:23:55.000000000 +0000
+++ b/Zend/zend_vm_execute.h	2025-11-18 21:43:27.149565685 +0000
@@ -23173,7 +23173,7 @@
 			while (1) {
 				if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
 					/* reached end of iteration */
-					goto fe_fetch_w_exit;
+					goto fe_fetch_w_exit_exc;
 				}
 				pos++;
 				value = &p->val;
@@ -23269,6 +23269,7 @@
 		}
 	} else {
 		zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array));
+fe_fetch_w_exit_exc:
 		if (UNEXPECTED(EG(exception))) {
 			UNDEF_RESULT();
 			HANDLE_EXCEPTION();
diff '--color=auto' -Naur a/Zend/zend_weakrefs.c b/Zend/zend_weakrefs.c
--- a/Zend/zend_weakrefs.c	2025-10-21 19:23:55.000000000 +0000
+++ b/Zend/zend_weakrefs.c	2025-11-18 21:43:27.150565698 +0000
@@ -722,7 +722,7 @@
 		RETURN_THROWS();
 	}
 
-	ZVAL_COPY(return_value, zv);
+	RETURN_COPY_DEREF(zv);
 }
 
 ZEND_METHOD(WeakMap, offsetSet)
diff '--color=auto' -Naur a/configure.ac b/configure.ac
--- a/configure.ac	2025-10-21 19:23:55.000000000 +0000
+++ b/configure.ac	2025-11-18 21:48:08.951188482 +0000
@@ -17,7 +17,7 @@
 dnl ----------------------------------------------------------------------------
 
 AC_PREREQ([2.68])
-AC_INIT([PHP],[8.4.14],[https://github.com/php/php-src/issues],[php],[https://www.php.net])
+AC_INIT([PHP],[8.4.15],[https://github.com/php/php-src/issues],[php],[https://www.php.net])
 AC_CONFIG_SRCDIR([main/php_version.h])
 AC_CONFIG_AUX_DIR([build])
 AC_PRESERVE_HELP_ORDER
diff '--color=auto' -Naur a/configure.ac.orig b/configure.ac.orig
--- a/configure.ac.orig	1970-01-01 00:00:00.000000000 +0000
+++ b/configure.ac.orig	2025-11-18 21:42:37.765926246 +0000
@@ -0,0 +1,1836 @@
+dnl Process this file with autoconf to produce a configure script.
+
+dnl Include external macro definitions before the AC_INIT to also remove
+dnl comments starting with # and empty newlines from the included files.
+dnl ----------------------------------------------------------------------------
+m4_include([build/ax_check_compile_flag.m4])
+m4_include([build/ax_func_which_gethostbyname_r.m4])
+m4_include([build/ax_gcc_func_attribute.m4])
+m4_include([build/libtool.m4])
+m4_include([build/php_cxx_compile_stdcxx.m4])
+m4_include([build/php.m4])
+m4_include([build/pkg.m4])
+m4_include([TSRM/threads.m4])
+m4_include([Zend/Zend.m4])
+
+dnl Basic autoconf initialization, generation of config.nice.
+dnl ----------------------------------------------------------------------------
+
+AC_PREREQ([2.68])
+AC_INIT([PHP],[8.4.14],[https://github.com/php/php-src/issues],[php],[https://www.php.net])
+AC_CONFIG_SRCDIR([main/php_version.h])
+AC_CONFIG_AUX_DIR([build])
+AC_PRESERVE_HELP_ORDER
+
+PHP_CONFIG_NICE([config.nice])
+
+PHP_CANONICAL_HOST_TARGET
+
+AC_CONFIG_HEADERS([main/php_config.h])
+
+AH_TOP([
+#ifndef PHP_CONFIG_H
+#define PHP_CONFIG_H
+
+#if defined(__GNUC__) && __GNUC__ >= 4
+# define ZEND_API __attribute__ ((visibility("default")))
+# define ZEND_DLEXPORT __attribute__ ((visibility("default")))
+#else
+# define ZEND_API
+# define ZEND_DLEXPORT
+#endif
+
+#define ZEND_DLIMPORT
+])
+AH_BOTTOM([
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include <string.h>
+
+#endif /* PHP_CONFIG_H */
+])
+
+ac_IFS=$IFS; IFS="."
+set $(echo AC_PACKAGE_VERSION | "${SED}" 's/\([[0-9\.]]*\)\(.*\)/\1\.\2/')
+IFS=$ac_IFS
+PHP_MAJOR_VERSION=[$]1
+PHP_MINOR_VERSION=[$]2
+PHP_RELEASE_VERSION=[$]3
+dnl Allow overriding PHP_EXTRA_VERSION through the homonymous env var
+AC_ARG_VAR([PHP_EXTRA_VERSION],
+  [Extra PHP version label suffix, e.g. '-dev', 'rc1', '-acme'])dnl
+AS_VAR_IF([PHP_EXTRA_VERSION],, [PHP_EXTRA_VERSION=[$]4])
+PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION"
+PHP_VERSION_ID=$(expr [$]PHP_MAJOR_VERSION \* 10000 + [$]PHP_MINOR_VERSION \* 100 + [$]PHP_RELEASE_VERSION)
+
+dnl Allow version values to be used in Makefile.
+PHP_SUBST([PHP_MAJOR_VERSION])
+PHP_SUBST([PHP_MINOR_VERSION])
+PHP_SUBST([PHP_RELEASE_VERSION])
+PHP_SUBST([PHP_EXTRA_VERSION])
+
+dnl Setting up the PHP version based on the information above.
+dnl ----------------------------------------------------------------------------
+
+echo "/* automatically generated by configure */" > php_version.h.new
+echo "/* edit configure.ac to change version number */" >> php_version.h.new
+echo "#define PHP_MAJOR_VERSION $PHP_MAJOR_VERSION" >> php_version.h.new
+echo "#define PHP_MINOR_VERSION $PHP_MINOR_VERSION" >> php_version.h.new
+echo "#define PHP_RELEASE_VERSION $PHP_RELEASE_VERSION" >> php_version.h.new
+echo "#define PHP_EXTRA_VERSION \"$PHP_EXTRA_VERSION\"" >> php_version.h.new
+echo "#define PHP_VERSION \"$PHP_VERSION\"" >> php_version.h.new
+echo "#define PHP_VERSION_ID $PHP_VERSION_ID" >> php_version.h.new
+cmp php_version.h.new $srcdir/main/php_version.h >/dev/null 2>&1
+if test $? -ne 0 ; then
+  rm -f $srcdir/main/php_version.h && mv php_version.h.new $srcdir/main/php_version.h && \
+  echo 'Updated main/php_version.h'
+else
+  rm -f php_version.h.new
+fi
+
+dnl Settings we want to make before the checks.
+dnl ----------------------------------------------------------------------------
+
+PHP_INIT_BUILD_SYSTEM
+
+dnl Because 'make install' is often performed by the superuser, we create the
+dnl libs subdirectory as the user who configures PHP. Otherwise, the current
+dnl user will not be able to delete libs or the contents of libs.
+
+$php_shtool mkdir -p libs
+rm -f libs/*
+
+dnl Checks for programs.
+dnl ----------------------------------------------------------------------------
+
+PKG_PROG_PKG_CONFIG
+AC_PROG_CC([cc gcc])
+PHP_DETECT_ICC
+PHP_DETECT_SUNCC
+
+dnl AC_PROG_CC_C99 is obsolete with autoconf >= 2.70 yet necessary for <= 2.69.
+m4_version_prereq([2.70],,[AC_PROG_CC_C99])
+AC_PROG_CPP
+AC_USE_SYSTEM_EXTENSIONS
+AC_PROG_LN_S
+
+AS_VAR_IF([cross_compiling], [yes],
+  [AC_CHECK_PROGS([BUILD_CC], [gcc clang c99 c89 cc cl], [none])
+    AC_MSG_CHECKING([for native build C compiler])
+    AC_MSG_RESULT([$BUILD_CC])],
+  [BUILD_CC=$CC])
+
+dnl Support systems with system libraries in e.g. /usr/lib64.
+PHP_ARG_WITH([libdir],
+  [for system library directory],
+  [AS_HELP_STRING([--with-libdir=NAME],
+    [Look for libraries in .../NAME rather than .../lib])],
+  [lib],
+  [no])
+
+PHP_ARG_ENABLE([rpath],
+  [whether to enable runpaths],
+  [AS_HELP_STRING([--disable-rpath],
+    [Disable passing additional runtime library search paths])],
+  [yes],
+  [no])
+
+dnl Check for -R, etc. switch.
+PHP_RUNPATH_SWITCH
+
+dnl Checks for some support/generator progs.
+PHP_PROG_BISON([3.0.0])
+PHP_PROG_RE2C([1.0.3], [--no-generation-date])
+dnl Find installed PHP. Minimum supported version for gen_stub.php is PHP 7.4.
+PHP_PROG_PHP([7.4])
+
+PHP_ARG_ENABLE([re2c-cgoto],
+  [whether to enable computed goto extension with re2c],
+  [AS_HELP_STRING([--enable-re2c-cgoto],
+    [Enable re2c -g flag to optimize conditional jumps using computed goto
+    extension, if supported by the compiler])],
+  [no],
+  [no])
+
+AS_VAR_IF([PHP_RE2C_CGOTO], [no],,
+[AC_CACHE_CHECK([whether re2c -g works], [php_cv_have_re2c_cgoto],
+  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+int main(void)
+{
+label1:
+  ;
+label2:
+  ;
+  static void *adr[] = { &&label1, &&label2 };
+  goto *adr[0];
+  return 0;
+}]])],
+  [php_cv_have_re2c_cgoto=yes],
+  [php_cv_have_re2c_cgoto=no])])
+AS_VAR_IF([php_cv_have_re2c_cgoto], [yes],
+  [AS_VAR_APPEND([RE2C_FLAGS], [" -g"])])
+])
+
+dnl Platform-specific compile settings.
+dnl ----------------------------------------------------------------------------
+
+dnl See bug #28605
+case $host_cpu in
+  alpha*)
+    if test "$GCC" = "yes"; then
+      CFLAGS="$CFLAGS -mieee"
+    else
+      CFLAGS="$CFLAGS -ieee"
+    fi
+    ;;
+  sparc*)
+    if test "$SUNCC" = "yes"; then
+      CFLAGS="$CFLAGS -xmemalign=8s"
+    fi
+    ;;
+esac
+
+dnl See https://github.com/php/php-src/issues/14140
+AX_CHECK_COMPILE_FLAG([-ffp-contract=off], [CFLAGS="$CFLAGS -ffp-contract=off"])
+
+dnl Mark symbols hidden by default if the compiler (for example, gcc >= 4)
+dnl supports it. This can help reduce the binary size and startup time.
+AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],
+                       [CFLAGS="$CFLAGS -fvisibility=hidden"])
+
+case $host_alias in
+  *solaris*)
+    CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
+    ;;
+  *hpux*)
+    if test "$GCC" = "yes"; then
+      CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED"
+    fi
+    ;;
+esac
+
+dnl Disable PIC mode by default where it is known to be safe to do so, to avoid
+dnl the performance hit from the lost register.
+AC_MSG_CHECKING([whether to force non-PIC code in shared modules])
+case $host_alias in
+  i?86-*-linux*|i?86-*-freebsd*)
+    if test "${with_pic+set}" != "set" || test "$with_pic" = "no"; then
+      with_pic=no
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+esac
+
+dnl Detect musl libc
+AC_MSG_CHECKING([whether we are using musl libc])
+if command -v ldd >/dev/null && ldd --version 2>&1 | grep ^musl >/dev/null 2>&1
+then
+  AC_MSG_RESULT([yes])
+  AC_DEFINE([__MUSL__], [1], [Define to 1 when using musl libc.])
+else
+  AC_MSG_RESULT([no])
+fi
+
+dnl Add _GNU_SOURCE compile definition because the php_config.h with definitions
+dnl by AC_USE_SYSTEM_EXTENSIONS might be included after the system headers which
+dnl require extensions to C and POSIX.
+AS_VAR_APPEND([CPPFLAGS], [" -D_GNU_SOURCE"])
+
+PTHREADS_CHECK
+PHP_HELP_SEPARATOR([SAPI modules:])
+PHP_SHLIB_SUFFIX_NAMES
+PHP_BUILD_PROGRAM
+PHP_SAPI=none
+
+dnl SAPI configuration.
+dnl ----------------------------------------------------------------------------
+
+dnl Paths to the targets are relative to the build directory.
+SAPI_LIBNAME=libphp
+SAPI_LIBNAME_SHARED=$SAPI_LIBNAME.[]$SHLIB_DL_SUFFIX_NAME
+SAPI_LIBNAME_STATIC=$SAPI_LIBNAME.a
+SAPI_SHARED=libs/$SAPI_LIBNAME_SHARED
+SAPI_STATIC=libs/$SAPI_LIBNAME_STATIC
+SAPI_LIBTOOL=libphp.la
+
+PHP_CONFIGURE_PART([Configuring SAPI modules])
+
+esyscmd(./build/config-stubs sapi)
+
+dnl Show which main SAPI was selected.
+AC_MSG_CHECKING([for chosen SAPI module])
+AC_MSG_RESULT([$PHP_SAPI])
+
+dnl Show which binaries were selected.
+AC_MSG_CHECKING([for executable SAPI binaries])
+AS_VAR_IF([PHP_BINARIES],,
+  [AC_MSG_RESULT([none])],
+  [AC_MSG_RESULT([$PHP_BINARIES])])
+
+dnl Exit early.
+AS_VAR_IF([PHP_INSTALLED_SAPIS],, [AC_MSG_ERROR([Nothing to build.])])
+
+dnl Add POSIX threads compilation and linker flags when thread safety is enabled
+dnl with either the '--enable-zts' configure option or automatically enabled by
+dnl PHP SAPIs. For example, Apache SAPI.
+AS_VAR_IF([enable_zts], [yes], [
+  if test -n "$ac_cv_pthreads_lib"; then
+    LIBS="$LIBS -l$ac_cv_pthreads_lib"
+  fi
+  if test -n "$ac_cv_pthreads_cflags"; then
+    CFLAGS="$CFLAGS $ac_cv_pthreads_cflags"
+  fi
+
+  PTHREADS_FLAGS
+])
+
+dnl Starting system checks.
+dnl ----------------------------------------------------------------------------
+
+PHP_CONFIGURE_PART([Running system checks])
+
+dnl Find sendmail binary.
+PHP_PROG_SENDMAIL
+
+dnl Check whether the system uses EBCDIC (not ASCII) as its native codeset.
+PHP_EBCDIC
+
+dnl Check whether the system byte ordering is bigendian.
+PHP_C_BIGENDIAN
+
+dnl Check whether writing to stdout works.
+PHP_TEST_WRITE_STDOUT
+
+dnl Check for /usr/pkg/{lib,include} which is where NetBSD puts binary and
+dnl source packages. This should be harmless on other OSs.
+if test -d /usr/pkg/include && test -d /usr/pkg/lib; then
+   CPPFLAGS="$CPPFLAGS -I/usr/pkg/include"
+   LDFLAGS="$LDFLAGS -L/usr/pkg/lib"
+fi
+test -d /usr/ucblib && PHP_ADD_LIBPATH([/usr/ucblib])
+
+dnl First, library checks.
+dnl ----------------------------------------------------------------------------
+
+AC_SEARCH_LIBS([socket], [socket network])
+
+AC_CHECK_FUNCS([socketpair],,
+  [AC_SEARCH_LIBS([socketpair], [socket network],
+    [AC_DEFINE([HAVE_SOCKETPAIR], [1])])])
+
+AC_SEARCH_LIBS([gethostbyaddr], [nsl network])
+
+AC_SEARCH_LIBS([dlopen], [dl],
+  [AC_DEFINE([HAVE_LIBDL], [1],
+    [Define to 1 if you have the 'dl' library (-ldl).])])
+
+AC_SEARCH_LIBS([sin], [m])
+
+case $host_alias in
+  riscv64*)
+    PHP_CHECK_FUNC(__atomic_exchange_1, atomic)
+    ;;
+esac
+
+dnl Solaris/Illumos for process mapping.
+AC_SEARCH_LIBS([Pgrab], [proc])
+
+dnl Haiku does not have network api in libc.
+AC_SEARCH_LIBS([setsockopt], [network])
+
+dnl Check for openpty. It may require linking against libutil or libbsd.
+AC_CHECK_FUNCS([openpty],,
+  [AC_SEARCH_LIBS([openpty], [util bsd], [AC_DEFINE([HAVE_OPENPTY], [1])])])
+
+dnl Then headers.
+dnl ----------------------------------------------------------------------------
+
+dnl QNX requires unix.h to allow functions in libunix to work properly.
+AC_CHECK_HEADERS(m4_normalize([
+  dirent.h
+  sys/param.h
+  sys/types.h
+  sys/time.h
+  netinet/in.h
+  alloca.h
+  arpa/inet.h
+  arpa/nameser.h
+  dns.h
+  fcntl.h
+  grp.h
+  ieeefp.h
+  langinfo.h
+  linux/sock_diag.h
+  poll.h
+  pty.h
+  pwd.h
+  resolv.h
+  strings.h
+  syslog.h
+  sysexits.h
+  sys/ioctl.h
+  sys/file.h
+  sys/mman.h
+  sys/mount.h
+  sys/poll.h
+  sys/resource.h
+  sys/select.h
+  sys/socket.h
+  sys/stat.h
+  sys/statfs.h
+  sys/statvfs.h
+  sys/vfs.h
+  sys/sysexits.h
+  sys/uio.h
+  sys/wait.h
+  sys/loadavg.h
+  unistd.h
+  unix.h
+  utime.h
+  sys/utsname.h
+  sys/ipc.h
+  dlfcn.h
+  tmmintrin.h
+  nmmintrin.h
+  wmmintrin.h
+  immintrin.h
+]),,, [dnl
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#include <arpa/nameser.h>
+#endif
+])
+
+PHP_FOPENCOOKIE
+PHP_BROKEN_GETCWD
+AS_VAR_IF([GCC], [yes], [PHP_BROKEN_GCC_STRLEN_OPT])
+
+dnl Detect the headers required to use makedev, major, and minor.
+dnl Autoconf <= 2.69 didn't check glibc 2.25 deprecated macros in sys/types.h.
+m4_version_prereq([2.70],,[ac_cv_header_sys_types_h_makedev=no])
+AC_HEADER_MAJOR
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+dnl ----------------------------------------------------------------------------
+
+AC_STRUCT_TIMEZONE
+
+PHP_MISSING_TIME_R_DECL
+
+AC_CHECK_TYPES([struct flock],,,[#include <fcntl.h>])
+AC_CHECK_TYPES([socklen_t], [], [], [
+  #ifdef HAVE_SYS_TYPES_H
+  # include <sys/types.h>
+  #endif
+  #ifdef HAVE_SYS_SOCKET_H
+  # include <sys/socket.h>
+  #endif
+])
+
+dnl These are defined elsewhere than stdio.h.
+PHP_CHECK_SIZEOF([intmax_t], [0])
+PHP_CHECK_SIZEOF([ssize_t], [8])
+PHP_CHECK_SIZEOF([ptrdiff_t], [8])
+
+dnl Check stdint types (must be after header check).
+PHP_CHECK_STDINT_TYPES
+
+dnl Check GNU C builtins.
+PHP_CHECK_BUILTIN([__builtin_clz])
+PHP_CHECK_BUILTIN([__builtin_clzl])
+PHP_CHECK_BUILTIN([__builtin_clzll])
+PHP_CHECK_BUILTIN([__builtin_cpu_init])
+PHP_CHECK_BUILTIN([__builtin_cpu_supports])
+PHP_CHECK_BUILTIN([__builtin_ctzl])
+PHP_CHECK_BUILTIN([__builtin_ctzll])
+PHP_CHECK_BUILTIN([__builtin_expect])
+PHP_CHECK_BUILTIN([__builtin_frame_address])
+PHP_CHECK_BUILTIN([__builtin_saddl_overflow])
+PHP_CHECK_BUILTIN([__builtin_saddll_overflow])
+PHP_CHECK_BUILTIN([__builtin_smull_overflow])
+PHP_CHECK_BUILTIN([__builtin_smulll_overflow])
+PHP_CHECK_BUILTIN([__builtin_ssubl_overflow])
+PHP_CHECK_BUILTIN([__builtin_ssubll_overflow])
+PHP_CHECK_BUILTIN([__builtin_unreachable])
+PHP_CHECK_BUILTIN([__builtin_usub_overflow])
+
+dnl Check AVX512
+PHP_CHECK_AVX512_SUPPORTS
+dnl Check AVX512 VBMI
+PHP_CHECK_AVX512_VBMI_SUPPORTS
+
+dnl Check for __alignof__ support in the compiler
+AC_CACHE_CHECK([whether the compiler supports __alignof__],
+[php_cv_have_alignof],
+[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [
+  int align = __alignof__(int);
+  (void)align;
+])],
+[php_cv_have_alignof=yes],
+[php_cv_have_alignof=no])])
+AS_VAR_IF([php_cv_have_alignof], [yes],
+  [AC_DEFINE([HAVE_ALIGNOF], [1],
+    [Define to 1 if the compiler supports '__alignof__'.])])
+
+dnl Check for structure members.
+AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,[#include <time.h>])
+AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_rdev])
+dnl AC_STRUCT_ST_BLOCKS will screw QNX because fileblocks.o does not exist.
+if test "$(uname -s 2>/dev/null)" != "QNX"; then
+  AC_STRUCT_ST_BLOCKS
+fi
+
+dnl Checks for types.
+AC_TYPE_UID_T
+
+dnl Checks for sockaddr_storage and sockaddr.sa_len.
+AC_CHECK_TYPES([struct sockaddr_storage],,,[#include <sys/socket.h>])
+AC_CHECK_MEMBERS([struct sockaddr.sa_len],,,[#include <sys/socket.h>])
+
+dnl Checks for GCC function attributes on all systems except ones without glibc
+dnl Fix for these systems is already included in GCC 7, but not on GCC 6.
+dnl
+dnl At least some versions of FreeBSD seem to have buggy ifunc support, see
+dnl bug #77284. Conservatively don't use ifuncs on FreeBSD prior to version 12.
+AS_CASE([$host_alias], [*-*-*android*|*-*-*uclibc*|*-*-*musl*|*openbsd*], [true], [
+  if test "$(uname -s 2>/dev/null)" != "FreeBSD" || test "$(uname -U 2>/dev/null)" -ge 1200000; then
+    AX_GCC_FUNC_ATTRIBUTE([ifunc])
+    AX_GCC_FUNC_ATTRIBUTE([target])
+  fi
+])
+
+dnl Check for __attribute__ ((__aligned__)) support in the compiler.
+PHP_CHECK_VARIABLE_ATTRIBUTE([aligned])
+
+dnl Checks for library functions.
+dnl ----------------------------------------------------------------------------
+
+AC_CHECK_FUNCS(m4_normalize([
+  alphasort
+  asctime_r
+  asprintf
+  chroot
+  ctime_r
+  explicit_memset
+  fdatasync
+  flock
+  ftok
+  funopen
+  gai_strerror
+  getcwd
+  getgrnam_r
+  gethostname
+  getloadavg
+  getlogin
+  getprotobyname
+  getprotobynumber
+  getpwnam_r
+  getpwuid_r
+  getrusage
+  getservbyname
+  getservbyport
+  gettimeofday
+  getwd
+  glob
+  gmtime_r
+  lchown
+  localtime_r
+  memcntl
+  memfd_create
+  memmem
+  mempcpy
+  memrchr
+  mkstemp
+  mmap
+  nice
+  nl_langinfo
+  poll
+  pthread_jit_write_protect_np
+  putenv
+  scandir
+  setenv
+  setitimer
+  shutdown
+  sigprocmask
+  statfs
+  statvfs
+  std_syslog
+  strcasecmp
+  strnlen
+  strptime
+  strtok_r
+  symlink
+  tzset
+  unsetenv
+  usleep
+  utime
+  vasprintf
+]))
+
+AC_CHECK_FUNC([inet_ntop],, [AC_MSG_FAILURE([Required inet_ntop not found.])])
+AC_CHECK_FUNC([inet_pton],, [AC_MSG_FAILURE([Required inet_pton not found.])])
+
+dnl Check for strerror_r, and if its a POSIX-compatible or a GNU specific version.
+AC_FUNC_STRERROR_R
+
+dnl Check for functions inside their belonging headers.
+AC_CHECK_HEADER([sys/prctl.h], [AC_CHECK_FUNCS([prctl])])
+AC_CHECK_HEADER([sys/procctl.h], [AC_CHECK_FUNCS([procctl])])
+
+AX_FUNC_WHICH_GETHOSTBYNAME_R
+
+dnl Some systems (Solaris 10) do not have nanosleep in libc.
+AC_CHECK_FUNCS([nanosleep],,
+  [AC_SEARCH_LIBS([nanosleep], [rt], [AC_DEFINE([HAVE_NANOSLEEP], [1])])])
+
+dnl Check for getaddrinfo, should be a better way, but... Also check for working
+dnl getaddrinfo.
+AC_CACHE_CHECK([for getaddrinfo], [php_cv_func_getaddrinfo],
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <netdb.h>],
+  [struct addrinfo *g,h;g=&h;getaddrinfo("","",g,&g);])],
+  [AC_RUN_IFELSE([AC_LANG_SOURCE([
+#include <netdb.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#ifndef AF_INET
+# include <sys/socket.h>
+#endif
+int main(void) {
+  struct addrinfo *ai, *pai, hints;
+
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_flags = AI_NUMERICHOST;
+
+  if (getaddrinfo("127.0.0.1", 0, &hints, &ai) < 0) {
+    return 1;
+  }
+
+  if (ai == 0) {
+    return 1;
+  }
+
+  pai = ai;
+
+  while (pai) {
+    if (pai->ai_family != AF_INET) {
+      /* 127.0.0.1/NUMERICHOST should only resolve ONE way */
+      return 1;
+    }
+    if (pai->ai_addr->sa_family != AF_INET) {
+      /* 127.0.0.1/NUMERICHOST should only resolve ONE way */
+      return 1;
+    }
+    pai = pai->ai_next;
+  }
+  freeaddrinfo(ai);
+  return 0;
+}
+  ])],
+  [php_cv_func_getaddrinfo=yes],
+  [php_cv_func_getaddrinfo=no],
+  [AS_CASE([$host_alias],
+    [*linux*|*midipix], [php_cv_func_getaddrinfo=yes],
+    [php_cv_func_getaddrinfo=no])])],
+[php_cv_func_getaddrinfo=no])])
+AS_VAR_IF([php_cv_func_getaddrinfo], [yes],
+  [AC_DEFINE([HAVE_GETADDRINFO], [1],
+    [Define to 1 if you have the 'getaddrinfo' function.])])
+
+dnl on FreeBSD, copy_file_range() works only with the undocumented flag 0x01000000;
+dnl until the problem is fixed properly, copy_file_range() is used only on Linux
+AC_CACHE_CHECK([for copy_file_range], [php_cv_func_copy_file_range],
+[AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+#ifndef __linux__
+# error "unsupported platform"
+#endif
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,3,0)
+# error "kernel too old"
+#endif
+#include <unistd.h>
+int main(void)
+{
+  (void)copy_file_range(-1, 0, -1, 0, 0, 0);
+  return 0;
+}
+])],
+[php_cv_func_copy_file_range=yes],
+[php_cv_func_copy_file_range=no])
+])
+AS_VAR_IF([php_cv_func_copy_file_range], [yes],
+  [AC_DEFINE([HAVE_COPY_FILE_RANGE], [1],
+    [Define to 1 if you have the 'copy_file_range' function.])])
+
+AC_REPLACE_FUNCS([strlcat strlcpy explicit_bzero getopt])
+AC_FUNC_ALLOCA
+PHP_TIME_R_TYPE
+
+AC_CACHE_CHECK([for aarch64 CRC32 API], [php_cv_func___crc32d],
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([
+#include <arm_acle.h>
+# if defined(__GNUC__)
+#  if!defined(__clang__)
+#   pragma GCC push_options
+#   pragma GCC target ("+nothing+crc")
+#  elif defined(__APPLE__)
+#   pragma clang attribute push(__attribute__((target("crc"))), apply_to=function)
+#  else
+#   pragma clang attribute push(__attribute__((target("+nothing+crc"))), apply_to=function)
+#  endif
+# endif
+], [__crc32d(0, 0);])],
+[php_cv_func___crc32d=yes],
+[php_cv_func___crc32d=no])])
+AS_VAR_IF([php_cv_func___crc32d], [yes],
+  [AC_DEFINE([HAVE_AARCH64_CRC32], [1],
+    [Define to 1 when aarch64 CRC32 API is available.])])
+
+dnl Check for asm goto support.
+AC_CACHE_CHECK([for asm goto], [php_cv_have__asm_goto],
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([], [
+#if defined(__x86_64__) || defined(__i386__)
+  __asm__ goto("jmp %l0\n" :::: end);
+#elif defined(__aarch64__)
+  __asm__ goto("b %l0\n" :::: end);
+#endif
+end:
+  return 0;
+])],
+[php_cv_have__asm_goto=yes],
+[php_cv_have__asm_goto=no])])
+AS_VAR_IF([php_cv_have__asm_goto], [yes],
+  [AC_DEFINE([HAVE_ASM_GOTO], [1],
+    [Define to 1 if asm goto support is available.])])
+
+dnl Check Valgrind support.
+PHP_ARG_WITH([valgrind],
+  [whether to enable Valgrind support],
+  [AS_HELP_STRING([--with-valgrind],
+    [Enable Valgrind support])],
+  [no],
+  [no])
+
+AS_VAR_IF([PHP_VALGRIND], [no],, [
+  PKG_CHECK_MODULES([VALGRIND], [valgrind],
+     [PHP_EVAL_INCLINE([$VALGRIND_CFLAGS])
+       AC_DEFINE([HAVE_VALGRIND], [1],
+        [Define to 1 if Valgrind is enabled and supported.])])
+  save_CFLAGS=$CFLAGS
+  CFLAGS="$CFLAGS $VALGRIND_CFLAGS"
+  AC_CHECK_HEADERS([valgrind/cachegrind.h])
+  CFLAGS=$save_CFLAGS
+])
+
+dnl General settings.
+dnl ----------------------------------------------------------------------------
+PHP_CONFIGURE_PART([General settings])
+
+PHP_HELP_SEPARATOR([General settings:])
+
+PHP_ARG_ENABLE([gcov],
+  [whether to include gcov symbols],
+  [AS_HELP_STRING([--enable-gcov],
+    [Enable GCOV code coverage - FOR DEVELOPERS ONLY!!])],
+  [no],
+  [no])
+
+AS_VAR_IF([PHP_GCOV], [yes], [
+  AS_VAR_IF([GCC], [yes],,
+    [AC_MSG_ERROR([GNU C compatible compiler is required for --enable-gcov])])
+
+  dnl Check if ccache is being used.
+  AS_CASE([$($php_shtool path $CC)],
+    [*ccache*], [gcc_ccache=yes],
+    [gcc_ccache=no])
+
+  if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then
+    AC_MSG_ERROR(m4_text_wrap([
+      ccache must be disabled when --enable-gcov option is used. You can disable
+      ccache by setting environment variable CCACHE_DISABLE=1.
+    ]))
+  fi
+
+  AC_DEFINE([HAVE_GCOV], [1], [Define to 1 if GCOV code coverage is enabled.])
+  PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/build/Makefile.gcov], [$abs_srcdir])
+
+  dnl Remove all optimization flags from CFLAGS.
+  PHP_REMOVE_OPTIMIZATION_FLAGS
+
+  dnl Add the special gcc flags.
+  CFLAGS="$CFLAGS -O0 -fprofile-arcs -ftest-coverage"
+  CXXFLAGS="$CXXFLAGS -O0 -fprofile-arcs -ftest-coverage"
+])
+
+PHP_ARG_ENABLE([debug],
+  [whether to include debugging symbols],
+  [AS_HELP_STRING([--enable-debug],
+    [Compile with debugging symbols])],
+  [no],
+  [no])
+
+AS_VAR_IF([PHP_DEBUG], [yes], [
+  PHP_DEBUG=1
+  ZEND_DEBUG=yes
+  PHP_REMOVE_OPTIMIZATION_FLAGS
+  dnl Add -O0 only if GCC or ICC is used.
+  if test "$GCC" = "yes" || test "$ICC" = "yes"; then
+    CFLAGS="$CFLAGS -O0"
+    CXXFLAGS="$CXXFLAGS -g -O0"
+  fi
+  if test "$SUNCC" = "yes"; then
+    if test -n "$auto_cflags"; then
+      CFLAGS="-g"
+      CXXFLAGS="-g"
+    else
+      CFLAGS="$CFLAGS -g"
+      CXXFLAGS="$CFLAGS -g"
+    fi
+  fi
+], [
+  PHP_DEBUG=0
+  ZEND_DEBUG=no
+])
+
+PHP_ARG_ENABLE([debug-assertions],
+  [whether to enable debug assertions in release mode],
+  [AS_HELP_STRING([--enable-debug-assertions],
+    [Compile with debug assertions even in release mode])],
+  [no],
+  [no])
+
+AS_VAR_IF([PHP_DEBUG_ASSERTIONS], [yes], [
+  PHP_DEBUG=1
+  ZEND_DEBUG=yes
+])
+
+AC_ARG_ENABLE([zts],
+  [AS_HELP_STRING([--enable-zts],
+    [Enable thread safety])],
+  [ZEND_ZTS=$enableval],
+  [ZEND_ZTS=no])
+
+AS_VAR_IF([ZEND_ZTS], [yes], [PHP_THREAD_SAFETY=yes], [PHP_THREAD_SAFETY=no])
+
+AS_VAR_IF([PHP_THREAD_SAFETY], [yes], [
+  AS_VAR_IF([pthreads_working], [yes], [],
+    [AC_MSG_FAILURE(m4_text_wrap([
+      Unable to verify system support for POSIX Threads, which are required for
+      PHP thread safety (ZTS) build.
+    ]))])
+
+  AC_MSG_CHECKING([for POSIX threads])
+  AC_MSG_RESULT([yes])
+])
+
+PHP_ARG_ENABLE([rtld-now],
+  [whether to dlopen extensions with RTLD_NOW instead of RTLD_LAZY],
+  [AS_HELP_STRING([--enable-rtld-now],
+    [Use dlopen with RTLD_NOW instead of RTLD_LAZY])],
+  [no],
+  [no])
+
+AS_VAR_IF([PHP_RTLD_NOW], [yes],
+  [AC_DEFINE([PHP_USE_RTLD_NOW], [1],
+    [Define to 1 if 'dlopen()' uses the 'RTLD_NOW' mode flag instead of
+    'RTLD_LAZY'.])])
+
+PHP_ARG_WITH([layout],
+  [layout of installed files],
+  [AS_HELP_STRING([--with-layout=TYPE],
+    [Set how installed files will be laid out. Type can be either PHP or GNU [PHP]])],
+  [PHP],
+  [no])
+
+AS_CASE([$PHP_LAYOUT], [GNU], [oldstyleextdir=no], [oldstyleextdir=yes])
+
+PHP_ARG_WITH([config-file-path],
+  [path to configuration file],
+  [AS_HELP_STRING([--with-config-file-path=PATH],
+    [Set the path in which to look for php.ini [PREFIX/lib]])],
+  [DEFAULT],
+  [no])
+
+AS_VAR_IF([PHP_CONFIG_FILE_PATH], [DEFAULT],
+  [AS_CASE([$PHP_LAYOUT],
+    [GNU], [PHP_CONFIG_FILE_PATH=$sysconfdir],
+    [PHP_CONFIG_FILE_PATH=$libdir])])
+
+AC_MSG_CHECKING([where to scan for configuration files])
+PHP_ARG_WITH([config-file-scan-dir],,
+  [AS_HELP_STRING([--with-config-file-scan-dir=PATH],
+    [Set the path where to scan for configuration files])],
+  [DEFAULT],
+  [no])
+
+AS_VAR_IF([PHP_CONFIG_FILE_SCAN_DIR], [DEFAULT], [PHP_CONFIG_FILE_SCAN_DIR=])
+AC_MSG_RESULT([$PHP_CONFIG_FILE_SCAN_DIR])
+
+PHP_ARG_ENABLE([sigchild],
+  [whether to enable PHP's own SIGCHLD handler],
+  [AS_HELP_STRING([--enable-sigchild],
+    [Enable PHP's own SIGCHLD handler])],
+  [no],
+  [no])
+
+AH_TEMPLATE([PHP_SIGCHILD],
+  [Define to 1 if PHP uses its own SIGCHLD handler, and to 0 if not.])
+AS_VAR_IF([PHP_SIGCHILD], [yes],
+  [AC_DEFINE([PHP_SIGCHILD], [1])],
+  [AC_DEFINE([PHP_SIGCHILD], [0])])
+
+PHP_ARG_ENABLE([libgcc],
+  [whether to explicitly link against libgcc],
+  [AS_HELP_STRING([--enable-libgcc],
+    [Enable explicitly linking against libgcc])],
+  [no],
+  [no])
+
+AS_VAR_IF([PHP_LIBGCC], [yes], [
+  PHP_LIBGCC_LIBPATH([gcc])
+  AS_VAR_IF([libgcc_libpath],,
+    [AC_MSG_ERROR([Cannot locate libgcc. Make sure that gcc is in your path])])
+  PHP_ADD_LIBPATH([$libgcc_libpath])
+  PHP_ADD_LIBRARY([gcc], [yes])
+])
+
+PHP_ARG_ENABLE([short-tags],
+  [whether to enable short tags by default],
+  [AS_HELP_STRING([--disable-short-tags],
+    [Disable the short-form <? start tag by default])],
+  [yes],
+  [no])
+
+AH_TEMPLATE([DEFAULT_SHORT_OPEN_TAG],
+  [Define to string "1" if PHP short open tags '<?' are enabled by default, and
+  to string "0" if they are not.])
+AS_VAR_IF([PHP_SHORT_TAGS], [yes],
+  [AC_DEFINE([DEFAULT_SHORT_OPEN_TAG], ["1"])],
+  [AC_DEFINE([DEFAULT_SHORT_OPEN_TAG], ["0"])])
+
+PHP_ARG_ENABLE([dmalloc],
+  [whether to enable dmalloc],
+  [AS_HELP_STRING([--enable-dmalloc],
+    [Enable dmalloc])],
+  [no],
+  [no])
+
+AS_VAR_IF([PHP_DMALLOC], [yes],
+  [AC_CHECK_LIB([dmalloc], [dmalloc_error],
+    [PHP_ADD_LIBRARY([dmalloc])
+      AC_DEFINE([HAVE_DMALLOC], [1], [Define to 1 if you have dmalloc.])
+      AS_VAR_APPEND([CPPFLAGS], [" -DDMALLOC_FUNC_CHECK"])],
+    [AC_MSG_FAILURE([The dmalloc check failed. Cannot enable dmalloc.])])])
+
+PHP_ARG_ENABLE([ipv6],
+  [whether to enable IPv6 support],
+  [AS_HELP_STRING([--disable-ipv6],
+    [Disable IPv6 support])],
+  [yes],
+  [no])
+
+AS_VAR_IF([PHP_IPV6], [yes],
+  [AC_CACHE_CHECK([for IPv6 support], [php_cv_have_ipv6],
+    [AC_LINK_IFELSE([AC_LANG_PROGRAM([
+      #include <sys/types.h>
+      #include <sys/socket.h>
+      #include <netinet/in.h>
+    ], [[
+      struct sockaddr_in6 s;
+      struct in6_addr t = in6addr_any;
+      int i = AF_INET6;
+      (void)s;
+      t.s6_addr[0] = 0;
+      (void)i;
+    ]])],
+    [php_cv_have_ipv6=yes],
+    [php_cv_have_ipv6=no])])
+])
+AS_VAR_IF([php_cv_have_ipv6], [yes],
+  [AC_DEFINE([HAVE_IPV6], [1],
+    [Define to 1 if IPv6 is enabled and supported.])])
+
+dnl DTRACE checks. Note: this has to be done after SAPI configuration.
+PHP_ARG_ENABLE([dtrace],
+  [whether to enable DTrace support],
+  [AS_HELP_STRING([--enable-dtrace],
+    [Enable DTrace support])],
+  [no],
+  [no])
+
+AS_VAR_IF([PHP_DTRACE], [yes], [
+  PHP_INIT_DTRACE([Zend/zend_dtrace.d], [Zend/zend_dtrace_gen.h], [
+    main/main.c
+    Zend/zend_API.c
+    Zend/zend_dtrace.c
+    Zend/zend_exceptions.c
+    Zend/zend_execute.c
+    Zend/zend.c
+  ])
+  AC_DEFINE([HAVE_DTRACE], [1], [Define to 1 if DTrace support is enabled.])
+])
+
+AC_MSG_CHECKING([how big to make fd sets])
+PHP_ARG_ENABLE([fd-setsize],,
+  [AS_HELP_STRING([--enable-fd-setsize],
+    [Set size of descriptor sets])],
+  [no],
+  [no])
+
+AS_VAR_IF([PHP_FD_SETSIZE], [no], [AC_MSG_RESULT([using system default])], [
+  if test "0$PHP_FD_SETSIZE" -gt 0 2>/dev/null; then
+    CPPFLAGS="$CPPFLAGS -DFD_SETSIZE=$PHP_FD_SETSIZE"
+    AC_MSG_RESULT([using $PHP_FD_SETSIZE])
+  else
+    AC_MSG_ERROR([Invalid value passed to --enable-fd-setsize!])
+  fi
+])
+
+PHP_ARG_ENABLE([werror],,
+  [AS_HELP_STRING([--enable-werror],
+    [Enable -Werror])],
+  [no],
+  [no])
+PHP_ARG_ENABLE([memory-sanitizer],,
+  [AS_HELP_STRING([--enable-memory-sanitizer],
+    [Enable memory sanitizer (clang only)])],
+  [no],
+  [no])
+PHP_ARG_ENABLE([address-sanitizer],,
+  [AS_HELP_STRING([--enable-address-sanitizer],
+    [Enable address sanitizer])],
+  [no],
+  [no])
+PHP_ARG_ENABLE([undefined-sanitizer],,
+  [AS_HELP_STRING([--enable-undefined-sanitizer],
+    [Enable undefined sanitizer])],
+  [no],
+  [no])
+
+dnl Extension configuration.
+dnl ----------------------------------------------------------------------------
+
+PHP_HELP_SEPARATOR([[Extensions:
+  --with-EXTENSION=[shared[,PATH]]
+
+    NOTE: Not all extensions can be built as 'shared'.
+
+    Example: --with-foobar=shared,/usr/local/foobar/
+
+      o Builds the foobar extension as shared extension.
+      o foobar package install prefix is /usr/local/foobar/
+]])
+
+PHP_CONFIGURE_PART([Configuring extensions])
+
+dnl Check if all enabled by default extensions should be disabled.
+AC_ARG_ENABLE([all],
+  [AS_HELP_STRING([--disable-all],
+    [Disable all extensions which are enabled by default])],
+  [PHP_ENABLE_ALL=$enableval])
+
+dnl Reading config stubs.
+esyscmd(./build/config-stubs ext)
+
+dnl Extensions post-config.
+dnl ----------------------------------------------------------------------------
+
+dnl Align segments on huge page boundary
+AS_CASE([$host_alias], [[i[3456]86-*-linux-* | x86_64-*-linux-*]],
+  [AC_CACHE_CHECK([linker support for -zcommon-page-size=2097152],
+    [php_cv_have_common_page_size], [
+    save_LDFLAGS=$LDFLAGS
+    LDFLAGS="$LDFLAGS -Wl,-zcommon-page-size=2097152 -Wl,-zmax-page-size=2097152"
+    AC_RUN_IFELSE([AC_LANG_PROGRAM()],
+      [php_cv_have_common_page_size=yes],
+      [php_cv_have_common_page_size=no],
+      [php_cv_have_common_page_size=no])
+    LDFLAGS=$save_LDFLAGS])
+  AS_VAR_IF([php_cv_have_common_page_size], [yes],
+    [EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM -Wl,-zcommon-page-size=2097152 -Wl,-zmax-page-size=2097152"],
+    [AC_CACHE_CHECK([linker support for -zmax-page-size=2097152],
+      [php_cv_have_max_page_size], [
+      save_LDFLAGS=$LDFLAGS
+      LDFLAGS="$LDFLAGS -Wl,-zmax-page-size=2097152"
+      AC_RUN_IFELSE([AC_LANG_PROGRAM()],
+        [php_cv_have_max_page_size=yes],
+        [php_cv_have_max_page_size=no],
+        [php_cv_have_max_page_size=no])
+      LDFLAGS=$save_LDFLAGS])
+    AS_VAR_IF([php_cv_have_max_page_size], [yes],
+      [EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM -Wl,-zmax-page-size=2097152"])
+  ])
+])
+
+enable_shared=yes
+enable_static=yes
+
+case $php_sapi_module in
+  shared[)]
+    if test "$PHP_CGI" = "no" && test "$PHP_CLI" = "no" && test "$PHP_FPM" = "no" && test "$PHP_LITESPEED" = "no" && test "$PHP_PHPDBG" = "no"; then
+      enable_static=no
+    fi
+    case $with_pic in
+      yes)
+        standard_libtool_flag='-prefer-pic'
+        ;;
+      no)
+        standard_libtool_flag='-prefer-non-pic'
+        ;;
+    esac
+    EXTRA_LDFLAGS="$EXTRA_LDFLAGS -avoid-version -module"
+    ;;
+  *[)]
+    standard_libtool_flag='-prefer-non-pic -static'
+    if test -z "$PHP_MODULES" && test -z "$PHP_ZEND_EX"; then
+      enable_shared=no
+    fi
+    ;;
+esac
+
+EXTRA_LIBS="$EXTRA_LIBS $DLIBS $LIBS"
+unset LIBS
+
+dnl PEAR
+dnl ----------------------------------------------------------------------------
+
+PHP_HELP_SEPARATOR([PEAR:])
+PHP_CONFIGURE_PART([Configuring PEAR])
+
+dnl If CLI is disabled disable PEAR.
+AS_VAR_IF([PHP_CLI], [no], [with_pear=no])
+
+PHP_ARG_WITH([pear],
+  [whether to install PEAR],
+  [AS_HELP_STRING([[--with-pear[=DIR]]],
+    [Install PEAR in DIR [PREFIX/lib/php]])],
+  [no],
+  [yes])
+
+AS_VAR_IF([PHP_PEAR], [no],, [
+  AC_MSG_WARN([The --with-pear option is deprecated])
+
+  dnl PEAR dependencies.
+  AS_VAR_IF([PHP_XML], [no], [AC_MSG_ERROR(m4_text_wrap([
+    PEAR requires XML to be enabled. Add '--enable-xml' to the configure line,
+    or disable PEAR (--without-pear).
+  ]))])
+
+  install_pear=install-pear
+
+  AS_VAR_IF([PHP_PEAR], [yes],
+    [AS_CASE([$PHP_LAYOUT],
+      [GNU], [PEAR_INSTALLDIR=$datadir/pear],
+      [PEAR_INSTALLDIR=$libdir/php])],
+    [PEAR_INSTALLDIR=$PHP_PEAR])
+
+  PHP_SUBST([PEAR_INSTALLDIR])
+  PHP_ADD_BUILD_DIR([pear])
+  PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/pear/Makefile.frag],
+    [$abs_srcdir/pear],
+    [pear])
+])
+
+dnl Configuring Zend and TSRM.
+dnl ----------------------------------------------------------------------------
+
+PHP_HELP_SEPARATOR([Zend:])
+PHP_CONFIGURE_PART([Configuring Zend])
+
+AC_ARG_ENABLE([fiber-asm],
+  [AS_HELP_STRING([--disable-fiber-asm],
+    [Disable the use of boost fiber assembly files])],
+  [fiber_asm=$enableval], [fiber_asm='yes'])
+
+AS_CASE([$host_cpu],
+  [x86_64*|amd64*], [fiber_cpu="x86_64"],
+  [x86*|amd*|i?86*|pentium], [fiber_cpu="i386"],
+  [aarch64*|arm64*], [fiber_cpu="arm64"],
+  [arm*], [fiber_cpu="arm32"],
+  [ppc64*|powerpc64*], [fiber_cpu="ppc64"],
+  [ppc*|powerpc*], [fiber_cpu="ppc32"],
+  [riscv64*], [fiber_cpu="riscv64"],
+  [sparc64], [fiber_cpu="sparc64"],
+  [s390x*], [fiber_cpu="s390x"],
+  [loongarch64*], [fiber_cpu="loongarch64"],
+  [mips64*], [fiber_cpu="mips64"],
+  [mips*], [fiber_cpu="mips32"],
+  [fiber_cpu="unknown"]
+)
+
+AS_CASE([$host_os],
+  [darwin*], [fiber_os="mac"],
+  [aix*|os400*], [fiber_os="aix"],
+  [freebsd*], [fiber_os="freebsd"],
+  [midipix], [fiber_os="midipix"],
+  [fiber_os="other"]
+)
+
+AS_CASE([$fiber_cpu],
+  [x86_64], [fiber_asm_file_prefix="x86_64_sysv"],
+  [i386], [fiber_asm_file_prefix="i386_sysv"],
+  [arm64], [fiber_asm_file_prefix="arm64_aapcs"],
+  [arm32], [fiber_asm_file_prefix="arm_aapcs"],
+  [ppc64], [fiber_asm_file_prefix="ppc64_sysv"],
+  [ppc32], [fiber_asm_file_prefix="ppc32_sysv"],
+  [riscv64], [fiber_asm_file_prefix="riscv64_sysv"],
+  [sparc64], [fiber_asm_file_prefix="sparc64_sysv"],
+  [s390x], [fiber_asm_file_prefix="s390x_sysv"],
+  [loongarch64], [fiber_asm_file_prefix="loongarch64_sysv"],
+  [mips64], [fiber_asm_file_prefix="mips64_n64"],
+  [mips32], [fiber_asm_file_prefix="mips32_o32"],
+  [fiber_asm_file_prefix="unknown"]
+)
+
+if test "$fiber_os" = 'mac'; then
+  fiber_asm_file="combined_sysv_macho_gas"
+elif test "$fiber_os" = 'aix'; then
+  # AIX uses a different calling convention (shared with non-_CALL_ELF Linux).
+  # The AIX assembler isn't GNU, but the file is compatible.
+  fiber_asm_file="${fiber_asm_file_prefix}_xcoff_gas"
+elif test "$fiber_os" = 'freebsd'; then
+  case $fiber_cpu in
+    i386*)
+      fiber_asm="no"
+      ;;
+    *)
+      fiber_asm_file="${fiber_asm_file_prefix}_elf_gas"
+      ;;
+  esac
+elif test "$fiber_os" = 'midipix'; then
+  case $fiber_cpu in
+    i386*)
+      fiber_asm="no"
+      ;;
+    x86_64)
+      fiber_asm_file="x86_64_ms_pe_gas"
+      ;;
+  esac
+elif test "$fiber_asm_file_prefix" != 'unknown'; then
+  fiber_asm_file="${fiber_asm_file_prefix}_elf_gas"
+else
+  fiber_asm="no"
+fi
+
+AC_CACHE_CHECK([whether syscall to create shadow stack exists],
+[php_cv_have_shadow_stack_syscall],
+[AC_RUN_IFELSE([AC_LANG_SOURCE([
+#include <unistd.h>
+#include <sys/mman.h>
+int main(void) {
+  /* test if syscall 451, i.e., map_shadow_stack is available */
+  void* base = (void *)syscall(451, 0, 0x20000, 0x1);
+  if (base != (void*)-1) {
+    munmap(base, 0x20000);
+    return 0;
+  }
+  return 1;
+}
+])],
+  [php_cv_have_shadow_stack_syscall=yes],
+  [php_cv_have_shadow_stack_syscall=no],
+  [php_cv_have_shadow_stack_syscall=no])
+])
+dnl The asm files can't see macro from AC_DEFINE, workaround this via cflag. If
+dnl the syscall doesn't exist, we may block the final ELF from __PROPERTY_SHSTK
+dnl via redefine macro as "-D__CET__=1".
+AS_VAR_IF([php_cv_have_shadow_stack_syscall], [yes],
+  [fiber_asm_cflag="-DSHADOW_STACK_SYSCALL=1"],
+  [fiber_asm_cflag="-DSHADOW_STACK_SYSCALL=0"])
+
+if test "$fiber_asm" = 'yes'; then
+  AC_MSG_CHECKING([for fiber switching context])
+  PHP_ADD_SOURCES([Zend/asm],
+    [make_${fiber_asm_file}.S jump_${fiber_asm_file}.S],
+    [$fiber_asm_cflag])
+  AC_MSG_RESULT([$fiber_asm_file])
+else
+  AS_VAR_IF([fiber_os], [mac], [AC_DEFINE([_XOPEN_SOURCE], [1], [ ])])
+  AC_CHECK_HEADER([ucontext.h],
+    [AC_DEFINE([ZEND_FIBER_UCONTEXT], [1],
+      [Define to 1 if Zend fiber uses ucontext instead of boost context.])],
+    [AC_MSG_FAILURE([fibers not available on this platform])])
+fi
+
+ZEND_INIT
+
+ZEND_EXTRA_LIBS=$LIBS
+unset LIBS
+
+PHP_ADD_INCLUDE([$abs_srcdir], [1])
+PHP_ADD_INCLUDE([$abs_srcdir/main], [1])
+PHP_ADD_INCLUDE([$abs_builddir], [1])
+PHP_ADD_INCLUDE([$abs_builddir/main], [1])
+PHP_ADD_INCLUDE([$abs_builddir/TSRM])
+PHP_ADD_INCLUDE([$abs_builddir/Zend])
+PHP_ADD_INCLUDE([$abs_srcdir/Zend])
+PHP_ADD_INCLUDE([$abs_srcdir/TSRM])
+
+EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LDFLAGS"
+EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM $LDFLAGS"
+unset LDFLAGS
+
+AC_ARG_PROGRAM
+
+AS_VAR_IF([prefix], [NONE], [prefix=/usr/local])
+AS_VAR_IF([exec_prefix], [NONE], [exec_prefix='${prefix}'])
+AS_VAR_IF([program_prefix], [NONE], [program_prefix=])
+AS_VAR_IF([program_suffix], [NONE], [program_suffix=])
+
+orig_libdir=$libdir
+AS_CASE([$libdir],
+  ['${exec_prefix}/lib'], [libdir=$libdir/php])
+
+AS_CASE([$(eval echo $datadir)],
+  ['${prefix}/share'], [datadir=$datadir/php])
+
+phptempdir=$(pwd)/libs
+
+old_exec_prefix=$exec_prefix
+old_libdir=$libdir
+old_datadir=$datadir
+exec_prefix=$(eval echo $exec_prefix)
+libdir=$(eval echo $libdir)
+datadir=$(eval eval echo $datadir)
+
+dnl Build extension directory path.
+ZEND_MODULE_API_NO=$($EGREP '#define ZEND_MODULE_API_NO ' $srcdir/Zend/zend_modules.h|"${SED}" 's/#define ZEND_MODULE_API_NO //')
+
+AC_ARG_VAR([EXTENSION_DIR],
+  [Default directory for dynamically loadable PHP extensions. If left empty, it
+  is determined automatically. Can be overridden using the PHP 'extension_dir'
+  INI directive.])
+AS_VAR_IF([EXTENSION_DIR],, [
+  extbasedir=$ZEND_MODULE_API_NO
+  AS_VAR_IF([oldstyleextdir], [yes], [
+    AS_VAR_IF([PHP_DEBUG], [1], [part1=debug], [part1=no-debug])
+    AS_VAR_IF([PHP_THREAD_SAFETY], [yes], [part2=zts], [part2=non-zts])
+    extbasedir=$part1-$part2-$extbasedir
+    EXTENSION_DIR=$libdir/extensions/$extbasedir
+  ], [
+    AS_VAR_IF([PHP_THREAD_SAFETY], [yes], [extbasedir=$extbasedir-zts])
+    AS_VAR_IF([PHP_DEBUG], [1], [extbasedir=$extbasedir-debug])
+    EXTENSION_DIR=$libdir/$extbasedir
+  ])
+])
+
+AS_CASE([$PHP_LAYOUT],
+  [GNU], [datarootdir=$prefix/share],
+  [datarootdir=$prefix/php])
+
+dnl Expand all directory names for use in macros/constants.
+EXPANDED_PEAR_INSTALLDIR=$(eval echo $PEAR_INSTALLDIR)
+EXPANDED_EXTENSION_DIR=$(eval echo $EXTENSION_DIR)
+EXPANDED_LOCALSTATEDIR=$(eval echo $localstatedir)
+EXPANDED_BINDIR=$(eval echo $bindir)
+EXPANDED_SBINDIR=$(eval echo $sbindir)
+EXPANDED_MANDIR=$(eval echo $mandir)
+EXPANDED_LIBDIR=$libdir
+EXPANDED_SYSCONFDIR=$(eval echo $sysconfdir)
+EXPANDED_DATADIR=$datadir
+EXPANDED_PHP_CONFIG_FILE_PATH=$(eval echo "$PHP_CONFIG_FILE_PATH")
+EXPANDED_PHP_CONFIG_FILE_SCAN_DIR=$(eval echo "$PHP_CONFIG_FILE_SCAN_DIR")
+INCLUDE_PATH=.:$EXPANDED_PEAR_INSTALLDIR
+
+exec_prefix=$old_exec_prefix
+libdir=$old_libdir
+datadir=$old_datadir
+
+AC_SUBST([INCLUDE_PATH])
+AC_SUBST([EXPANDED_PEAR_INSTALLDIR])
+AC_SUBST([EXPANDED_EXTENSION_DIR])
+AC_SUBST([EXPANDED_BINDIR])
+AC_SUBST([EXPANDED_SBINDIR])
+AC_SUBST([EXPANDED_MANDIR])
+AC_SUBST([EXPANDED_LIBDIR])
+AC_SUBST([EXPANDED_DATADIR])
+AC_SUBST([EXPANDED_SYSCONFDIR])
+AC_SUBST([EXPANDED_LOCALSTATEDIR])
+AC_SUBST([EXPANDED_PHP_CONFIG_FILE_PATH])
+AC_SUBST([EXPANDED_PHP_CONFIG_FILE_SCAN_DIR])
+AC_SUBST([PHP_INSTALLED_SAPIS])
+AC_SUBST([SAPI_LIBNAME_SHARED])
+AC_SUBST([SAPI_LIBNAME_STATIC])
+AC_SUBST([PHP_VERSION])
+AC_SUBST([PHP_VERSION_ID])
+AC_SUBST([PHP_LDFLAGS])
+
+PHP_UTILIZE_RPATHS
+
+PHP_REMOVE_USR_LIB([PHP_LDFLAGS])
+PHP_REMOVE_USR_LIB([LDFLAGS])
+
+EXTRA_LDFLAGS="$EXTRA_LDFLAGS $PHP_LDFLAGS"
+EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM $PHP_LDFLAGS"
+
+AC_ARG_VAR([PHP_UNAME],
+  [System information (defaults to the 'uname -a' output)])
+AS_VAR_IF([PHP_UNAME],, [PHP_UNAME=$(uname -a | xargs)])
+AC_DEFINE_UNQUOTED([PHP_UNAME], ["$PHP_UNAME"], [The 'uname -a' output.])
+
+PHP_OS=$(uname | xargs)
+AC_DEFINE_UNQUOTED([PHP_OS], ["$PHP_OS"], [The 'uname' output.])
+
+AC_ARG_VAR([PHP_BUILD_SYSTEM],
+  [The system that PHP was built on (defaults to the 'uname -a' output)])
+AS_VAR_IF([PHP_BUILD_SYSTEM],, [PHP_BUILD_SYSTEM=$PHP_UNAME])
+AC_DEFINE_UNQUOTED([PHP_BUILD_SYSTEM], ["$PHP_BUILD_SYSTEM"],
+  [The system that PHP was built on.])
+
+AC_ARG_VAR([PHP_BUILD_PROVIDER], [The PHP build provider information])
+AS_VAR_IF([PHP_BUILD_PROVIDER],,,
+  [AC_DEFINE_UNQUOTED([PHP_BUILD_PROVIDER], ["$PHP_BUILD_PROVIDER"],
+    [The PHP build provider information.])])
+
+AC_ARG_VAR([PHP_BUILD_COMPILER],
+  [Information about the compiler used for the PHP build])
+AS_VAR_IF([PHP_BUILD_COMPILER],,,
+  [AC_DEFINE_UNQUOTED([PHP_BUILD_COMPILER], ["$PHP_BUILD_COMPILER"],
+    [The compiler used for the PHP build.])])
+
+AC_ARG_VAR([PHP_BUILD_ARCH], [The build architecture])
+AS_VAR_IF([PHP_BUILD_ARCH],,,
+  [AC_DEFINE_UNQUOTED([PHP_BUILD_ARCH], ["$PHP_BUILD_ARCH"],
+    [The build architecture.])])
+
+PHP_SUBST([PHP_FASTCGI_OBJS])
+PHP_SUBST([PHP_SAPI_OBJS])
+PHP_SUBST([PHP_BINARY_OBJS])
+PHP_SUBST([PHP_GLOBAL_OBJS])
+PHP_SUBST([PHP_BINARIES])
+PHP_SUBST([PHP_MODULES])
+PHP_SUBST([PHP_ZEND_EX])
+PHP_SUBST([bindir])
+PHP_SUBST([sbindir])
+PHP_SUBST([exec_prefix])
+PHP_SUBST_OLD([program_prefix])
+PHP_SUBST_OLD([program_suffix])
+PHP_SUBST([includedir])
+PHP_SUBST_OLD([orig_libdir])
+PHP_SUBST([libdir])
+PHP_SUBST([mandir])
+PHP_SUBST([phptempdir])
+PHP_SUBST([prefix])
+PHP_SUBST([localstatedir])
+PHP_SUBST([datadir])
+PHP_SUBST([datarootdir])
+PHP_SUBST([sysconfdir])
+PHP_SUBST([EXEEXT])
+PHP_SUBST([CC])
+PHP_SUBST([BUILD_CC])
+PHP_SUBST([CFLAGS])
+PHP_SUBST([CFLAGS_CLEAN])
+PHP_SUBST([CPP])
+PHP_SUBST([CPPFLAGS])
+PHP_SUBST([CXX])
+PHP_SUBST([CXXFLAGS])
+PHP_SUBST([CXXFLAGS_CLEAN])
+PHP_SUBST_OLD([EXTENSION_DIR])
+PHP_SUBST([EXTRA_LDFLAGS])
+PHP_SUBST([EXTRA_LDFLAGS_PROGRAM])
+PHP_SUBST_OLD([EXTRA_LIBS])
+PHP_SUBST([ZEND_EXTRA_LIBS])
+PHP_SUBST([INCLUDES])
+PHP_SUBST([EXTRA_INCLUDES])
+PHP_SUBST([INSTALL_IT])
+PHP_SUBST([LIBTOOL])
+PHP_SUBST([LN_S])
+PHP_SUBST([NATIVE_RPATHS])
+PHP_SUBST([OVERALL_TARGET])
+PHP_SUBST([PHP_RPATHS])
+PHP_SUBST([PHP_SAPI])
+PHP_SUBST([SHELL])
+PHP_SUBST([PHP_FRAMEWORKS])
+PHP_SUBST([PHP_FRAMEWORKPATH])
+PHP_SUBST([INSTALL_HEADERS])
+
+if test "$PHP_THREAD_SAFETY" = "yes" && test -n "$ac_cv_pthreads_cflags"; then
+  CXXFLAGS="$CXXFLAGS $ac_cv_pthreads_cflags"
+  CPPFLAGS="$CPPFLAGS $ac_cv_pthreads_cflags"
+fi
+
+dnl Enable -Werror late, because it may break configure checks throwing warnings.
+AS_VAR_IF([PHP_WERROR], [yes], [
+  CFLAGS="$CFLAGS -Werror"
+  CXXFLAGS="$CXXFLAGS -Werror"
+])
+
+if test "$PHP_MEMORY_SANITIZER" = "yes" &&
+   test "$PHP_ADDRESS_SANITIZER" = "yes"; then
+   AC_MSG_ERROR([MemorySanitizer and AddressSanitizer are mutually exclusive])
+fi
+
+dnl Enable -fsanitize=memory late, because interceptors may break linking detection.
+AS_VAR_IF([PHP_MEMORY_SANITIZER], [yes],
+  [AX_CHECK_COMPILE_FLAG([-fsanitize=memory -fsanitize-memory-track-origins], [
+    CFLAGS="$CFLAGS -fsanitize=memory -fsanitize-memory-track-origins"
+    CXXFLAGS="$CXXFLAGS -fsanitize=memory -fsanitize-memory-track-origins"
+  ], [AC_MSG_ERROR([MemorySanitizer is not available])])
+])
+
+AS_VAR_IF([PHP_ADDRESS_SANITIZER], [yes],
+  [AS_VAR_IF([PHP_VALGRIND], [no],, [AC_MSG_ERROR(m4_text_wrap([
+    Valgrind and address sanitizer are not compatible. Either disable Valgrind
+    (remove --with-valgrind) or disable address sanitizer (remove
+    --enable-address-sanitizer).
+  ]))])
+
+  AX_CHECK_COMPILE_FLAG([-fsanitize=address], [
+    CFLAGS="$CFLAGS -fsanitize=address -DZEND_TRACK_ARENA_ALLOC"
+    CXXFLAGS="$CXXFLAGS -fsanitize=address -DZEND_TRACK_ARENA_ALLOC"
+  ], [AC_MSG_ERROR([AddressSanitizer is not available])])
+])
+
+AS_VAR_IF([PHP_UNDEFINED_SANITIZER], [yes],
+  [AX_CHECK_COMPILE_FLAG([-fsanitize=undefined], [
+    CFLAGS="$CFLAGS -fsanitize=undefined -fno-sanitize-recover=undefined"
+    CXXFLAGS="$CXXFLAGS -fsanitize=undefined -fno-sanitize-recover=undefined"
+    AX_CHECK_COMPILE_FLAG([-fno-sanitize=object-size], [
+      dnl Disable object-size sanitizer, because it is incompatible with our zend_function
+      dnl union, and this can't be easily fixed.
+      CFLAGS="$CFLAGS -fno-sanitize=object-size"
+      CXXFLAGS="$CFLAGS -fno-sanitize=object-size"
+    ])
+
+    dnl Clang 17 adds stricter function pointer compatibility checks where pointer args cannot be
+    dnl cast to void*. In that case, set -fno-sanitize=function.
+    OLD_CFLAGS=$CFLAGS
+    CFLAGS="$CFLAGS -fno-sanitize-recover=undefined"
+    AC_CACHE_CHECK([whether to add -fno-sanitize=function],
+    [php_cv_ubsan_no_function],
+    [AC_RUN_IFELSE([AC_LANG_SOURCE([
+      void foo(char *string) { (void)string; }
+      int main(void) {
+        void (*f)(void *) = (void (*)(void *))foo;
+        f("foo");
+        return 0;
+      }
+    ])],
+    [php_cv_ubsan_no_function=no],
+    [php_cv_ubsan_no_function=yes],
+    [php_cv_ubsan_no_function=no])])
+    CFLAGS=$OLD_CFLAGS
+    AS_VAR_IF([php_cv_ubsan_no_function], [yes], [
+      CFLAGS="$CFLAGS -fno-sanitize=function"
+      CXXFLAGS="$CFLAGS -fno-sanitize=function"
+    ])
+  ], [AC_MSG_ERROR([UndefinedBehaviorSanitizer is not available])])
+])
+
+if test "$PHP_MEMORY_SANITIZER" = "yes" ||
+   test "$PHP_ADDRESS_SANITIZER" = "yes" ||
+   test "$PHP_UNDEFINED_SANITIZER" = "yes"; then
+    CFLAGS="$CFLAGS -fno-omit-frame-pointer"
+    CXXFLAGS="$CXXFLAGS -fno-omit-frame-pointer"
+fi
+
+dnl
+dnl Libtool creation.
+dnl
+
+PHP_HELP_SEPARATOR([Libtool:])
+PHP_CONFIGURE_PART([Configuring libtool])
+
+dnl Silence warning: "ar: 'u' modifier ignored since 'D' is the default".
+dnl See https://github.com/php/php-src/pull/3017
+AC_SUBST([AR_FLAGS], [cr])
+
+dnl Only allow AC_PROG_CXX and AC_PROG_CXXCPP if they are explicitly called (by
+dnl PHP_REQUIRE_CXX). Otherwise AC_PROG_LIBTOOL fails if there is no working C++
+dnl compiler.
+AC_PROVIDE_IFELSE([PHP_REQUIRE_CXX], [], [
+  undefine([AC_PROG_CXX])
+  AC_DEFUN([AC_PROG_CXX], [])
+  undefine([AC_PROG_CXXCPP])
+  AC_DEFUN([AC_PROG_CXXCPP], [php_prog_cxxcpp=disabled])
+])
+AC_PROG_LIBTOOL
+
+PHP_SET_LIBTOOL_VARIABLE([--silent])
+
+dnl libtool 1.4.3 needs this.
+PHP_SET_LIBTOOL_VARIABLE([--preserve-dup-deps])
+
+PHP_CONFIGURE_PART([Generating files])
+
+CXXFLAGS_CLEAN=$CXXFLAGS
+CFLAGS_CLEAN="$CFLAGS \$(PROF_FLAGS)"
+CFLAGS="\$(CFLAGS_CLEAN) $standard_libtool_flag"
+CXXFLAGS="$CXXFLAGS $standard_libtool_flag \$(PROF_FLAGS)"
+
+if test "$PHP_PHAR" != "no" && test "$PHP_CLI" != "no"; then
+  pharcmd=pharcmd
+  pharcmd_install=install-pharcmd
+else
+  pharcmd=
+  pharcmd_install=
+fi;
+
+all_targets="\$(OVERALL_TARGET) \$(PHP_MODULES) \$(PHP_ZEND_EX) \$(PHP_BINARIES) $pharcmd"
+install_targets="$install_sapi $install_modules $install_binaries install-build install-headers install-programs $install_pear $pharcmd_install"
+
+PHP_SUBST([all_targets])
+PHP_SUBST([install_targets])
+PHP_SUBST([install_binary_targets])
+
+PHP_INSTALL_HEADERS([Zend/ TSRM/ main/ main/streams/])
+PHP_INSTALL_HEADERS([Zend/Optimizer], m4_normalize([
+  zend_call_graph.h
+  zend_cfg.h
+  zend_dfg.h
+  zend_dump.h
+  zend_func_info.h
+  zend_inference.h
+  zend_optimizer.h
+  zend_ssa.h
+  zend_worklist.h
+]))
+
+PHP_ADD_SOURCES([TSRM], [TSRM.c], [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+
+PHP_ADD_SOURCES([main], m4_normalize([
+    explicit_bzero.c
+    fopen_wrappers.c
+    getopt.c
+    main.c
+    network.c
+    output.c
+    php_content_types.c
+    php_ini_builder.c
+    php_ini.c
+    php_odbc_utils.c
+    php_open_temporary_file.c
+    php_scandir.c
+    php_syslog.c
+    php_ticks.c
+    php_variables.c
+    reentrancy.c
+    rfc1867.c
+    safe_bcmp.c
+    SAPI.c
+    snprintf.c
+    spprintf.c
+    strlcat.c
+    strlcpy.c
+  ]),
+  [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+
+if printf "#if __ELF__\nelf\n#endif\n" | $CC -E - | grep elf > /dev/null; then
+  PHP_ADD_SOURCES([main], [debug_gdb_scripts.c])
+
+  cat >> Makefile.objects <<EOF
+$abs_srcdir/main/debug_gdb_scripts.c: $abs_srcdir/scripts/gdb/debug_gdb_scripts_gen.php $abs_srcdir/scripts/gdb/php_gdb.py $abs_srcdir/.gdbinit
+	@if test ! -z "\$(PHP)"; then \\
+		\$(PHP) $abs_srcdir/scripts/gdb/debug_gdb_scripts_gen.php; \\
+	fi;
+EOF
+fi
+
+PHP_ADD_SOURCES_X([main],
+  [fastcgi.c],
+  [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1],
+  [PHP_FASTCGI_OBJS],
+  [no])
+
+PHP_ADD_SOURCES([main/streams], m4_normalize([
+    cast.c
+    filter.c
+    glob_wrapper.c
+    memory.c
+    mmap.c
+    plain_wrapper.c
+    streams.c
+    transports.c
+    userspace.c
+    xp_socket.c
+  ]),
+  [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+
+PHP_ADD_SOURCES([/main],
+  [internal_functions.c],
+  [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1],
+  [sapi])
+PHP_ADD_SOURCES_X([/main],
+  [internal_functions_cli.c],
+  [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1],
+  [PHP_BINARY_OBJS])
+
+PHP_ADD_SOURCES([Zend], m4_normalize([
+    Optimizer/block_pass.c
+    Optimizer/compact_literals.c
+    Optimizer/compact_vars.c
+    Optimizer/dce.c
+    Optimizer/dfa_pass.c
+    Optimizer/escape_analysis.c
+    Optimizer/nop_removal.c
+    Optimizer/optimize_func_calls.c
+    Optimizer/optimize_temp_vars_5.c
+    Optimizer/pass1.c
+    Optimizer/pass3.c
+    Optimizer/sccp.c
+    Optimizer/scdf.c
+    Optimizer/zend_call_graph.c
+    Optimizer/zend_cfg.c
+    Optimizer/zend_dfg.c
+    Optimizer/zend_dump.c
+    Optimizer/zend_func_info.c
+    Optimizer/zend_inference.c
+    Optimizer/zend_optimizer.c
+    Optimizer/zend_ssa.c
+    zend_alloc.c
+    zend_API.c
+    zend_ast.c
+    zend_atomic.c
+    zend_attributes.c
+    zend_builtin_functions.c
+    zend_call_stack.c
+    zend_closures.c
+    zend_compile.c
+    zend_constants.c
+    zend_cpuinfo.c
+    zend_default_classes.c
+    zend_dtrace.c
+    zend_enum.c
+    zend_exceptions.c
+    zend_execute_API.c
+    zend_execute.c
+    zend_extensions.c
+    zend_fibers.c
+    zend_float.c
+    zend_frameless_function.c
+    zend_gc.c
+    zend_gdb.c
+    zend_generators.c
+    zend_hash.c
+    zend_highlight.c
+    zend_hrtime.c
+    zend_inheritance.c
+    zend_ini_parser.c
+    zend_ini_scanner.c
+    zend_ini.c
+    zend_interfaces.c
+    zend_iterators.c
+    zend_language_parser.c
+    zend_language_scanner.c
+    zend_lazy_objects.c
+    zend_list.c
+    zend_llist.c
+    zend_max_execution_timer.c
+    zend_multibyte.c
+    zend_object_handlers.c
+    zend_objects_API.c
+    zend_objects.c
+    zend_observer.c
+    zend_opcode.c
+    zend_operators.c
+    zend_property_hooks.c
+    zend_ptr_stack.c
+    zend_signal.c
+    zend_smart_str.c
+    zend_sort.c
+    zend_stack.c
+    zend_stream.c
+    zend_string.c
+    zend_strtod.c
+    zend_system_id.c
+    zend_variables.c
+    zend_virtual_cwd.c
+    zend_vm_opcodes.c
+    zend_weakrefs.c
+    zend.c
+  ]),
+  [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $fiber_asm_cflag])
+
+PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/scripts/Makefile.frag],
+  [$abs_srcdir/scripts],
+  [scripts])
+PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/Zend/Makefile.frag],
+  [$abs_srcdir/Zend],
+  [Zend])
+
+AC_DEFINE([HAVE_BUILD_DEFS_H], [1],
+  [Define to 1 if PHP has the <main/build-defs.h> header file.])
+
+PHP_ADD_BUILD_DIR([
+  main
+  main/streams
+  scripts
+  scripts/man1
+  TSRM
+  Zend
+  Zend/asm
+  Zend/Optimizer
+])
+
+AC_CONFIG_FILES([
+  main/build-defs.h
+  scripts/man1/php-config.1
+  scripts/man1/phpize.1
+  scripts/php-config
+  scripts/phpize
+])
+
+AC_CONFIG_COMMANDS_PRE([PHP_PATCH_CONFIG_HEADERS([main/php_config.h.in])])
+
+AC_CONFIG_COMMANDS([Zend/zend_config.h], [
+cat >Zend/zend_config.h <<FEO
+#include <../main/php_config.h>
+FEO
+])
+
+AC_CONFIG_COMMANDS([main/internal_functions.c], [], [
+  AWK="$AWK" $SHELL $srcdir/build/genif.sh \
+    $srcdir/main/internal_functions.c.in \
+    "$EXT_STATIC" > main/internal_functions.c
+])
+
+AC_CONFIG_COMMANDS([main/internal_functions_cli.c], [], [
+  AWK="$AWK" $SHELL $srcdir/build/genif.sh \
+    $srcdir/main/internal_functions.c.in \
+    "$EXT_CLI_STATIC" > main/internal_functions_cli.c
+])
+
+AC_CONFIG_COMMANDS([default], [
+cat <<X
+
++--------------------------------------------------------------------+
+| License:                                                           |
+| This software is subject to the PHP License, available in this     |
+| distribution in the file LICENSE. By continuing this installation  |
+| process, you are bound by the terms of this license agreement.     |
+| If you do not agree with the terms of this license, you must abort |
+| the installation process at this point.                            |
++--------------------------------------------------------------------+
+
+Thank you for using PHP.
+
+X
+])
+AC_OUTPUT
diff '--color=auto' -Naur a/ext/ctype/tests/lc_ctype_inheritance.phpt b/ext/ctype/tests/lc_ctype_inheritance.phpt
--- a/ext/ctype/tests/lc_ctype_inheritance.phpt	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/ctype/tests/lc_ctype_inheritance.phpt	2025-11-18 21:43:27.152659491 +0000
@@ -4,6 +4,9 @@
 ctype
 --SKIPIF--
 <?php
+if (PHP_OS_FAMILY === 'Darwin' && version_compare(php_uname('r'), '24.0.0', '>=')) {
+    die('skip macOS 15 inherits LC_CTYPE into the thread locale');
+}
 if (setlocale(LC_ALL, 'invalid') === 'invalid') { die('skip setlocale() is broken /w musl'); }
 if (!setlocale(LC_CTYPE, "de_DE", "de-DE")) die("skip requires de_DE locale");
 ?>
diff '--color=auto' -Naur a/ext/dom/html5_parser.c b/ext/dom/html5_parser.c
--- a/ext/dom/html5_parser.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/dom/html5_parser.c	2025-11-18 21:43:27.152891990 +0000
@@ -268,7 +268,10 @@
 
                 /* xmlIsID does some other stuff too that is irrelevant here. */
                 if (local_name_length == 2 && local_name[0] == 'i' && local_name[1] == 'd' && attr->node.ns == LXB_NS_HTML) {
-                    xmlAddID(NULL, lxml_doc, value, lxml_attr);
+                    if (xmlAddID(NULL, lxml_doc, value, lxml_attr) == 0) {
+                        /* If the ID already exists, the ID attribute still needs to be marked as an ID. */
+                        lxml_attr->atype = XML_ATTRIBUTE_ID;
+                    }
                 }
 
                 /* libxml2 doesn't support line numbers on this anyway, it derives them instead, so don't bother */
diff '--color=auto' -Naur a/ext/dom/php_dom.c b/ext/dom/php_dom.c
--- a/ext/dom/php_dom.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/dom/php_dom.c	2025-11-18 21:43:27.153565737 +0000
@@ -492,6 +492,7 @@
 	zend_std_unset_property(object, member, cache_slot);
 }
 
+/* This custom handler is necessary to avoid a recursive construction of the entire subtree. */
 static HashTable* dom_get_debug_info_helper(zend_object *object, int *is_temp) /* {{{ */
 {
 	dom_object			*obj = php_dom_obj_from_obj(object);
@@ -502,6 +503,11 @@
 	dom_prop_handler	*entry;
 	zend_string         *object_str;
 
+	/* As we have a custom implementation, we must manually check for overrides. */
+	if (object->ce->__debugInfo) {
+		return zend_std_get_debug_info(object, is_temp);
+	}
+
 	*is_temp = 1;
 
 	std_props = zend_std_get_properties(object);
diff '--color=auto' -Naur a/ext/dom/tests/gh16317.phpt b/ext/dom/tests/gh16317.phpt
--- a/ext/dom/tests/gh16317.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/dom/tests/gh16317.phpt	2025-11-18 21:43:27.154367395 +0000
@@ -0,0 +1,20 @@
+--TEST--
+GH-16317 (DOM classes do not allow __debugInfo() overrides to work)
+--FILE--
+<?php
+
+class Demo extends DOMNode {
+    public function __construct() {}
+    public function __debugInfo(): array {
+        return ['x' => 'y'];
+    }
+}
+
+var_dump(new Demo());
+
+?>
+--EXPECT--
+object(Demo)#1 (1) {
+  ["x"]=>
+  string(1) "y"
+}
diff '--color=auto' -Naur a/ext/dom/tests/modern/html/interactions/gh20281.phpt b/ext/dom/tests/modern/html/interactions/gh20281.phpt
--- a/ext/dom/tests/modern/html/interactions/gh20281.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/dom/tests/modern/html/interactions/gh20281.phpt	2025-11-18 21:43:27.154503051 +0000
@@ -0,0 +1,15 @@
+--TEST--
+GH-20281 (\Dom\Document::getElementById() is inconsistent after nodes are removed)
+--EXTENSIONS--
+dom
+--CREDITS--
+cscott
+--FILE--
+<?php
+$d = \Dom\HTMLDocument::createFromString('<p id="a">b</p><p id="a">c</p>', LIBXML_NOERROR);
+$p = $d->getElementById('a');
+$p->remove();
+echo $d->getElementById('a')->textContent, "\n";
+?>
+--EXPECT--
+c
diff '--color=auto' -Naur a/ext/exif/exif.c b/ext/exif/exif.c
--- a/ext/exif/exif.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/exif/exif.c	2025-11-18 21:43:27.154692138 +0000
@@ -3249,6 +3249,7 @@
 
 #define REQUIRE_NON_EMPTY() do { \
 	if (byte_count == 0) { \
+		EFREE_IF(outside); \
 		exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Cannot be empty", tag, exif_get_tagname_debug(tag, tag_table)); \
 		return false; \
 	} \
diff '--color=auto' -Naur a/ext/ftp/ftp.c b/ext/ftp/ftp.c
--- a/ext/ftp/ftp.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/ftp/ftp.c	2025-11-18 21:43:27.156215014 +0000
@@ -1625,7 +1625,7 @@
 
 /* {{{ data_available */
 int
-data_available(ftpbuf_t *ftp, php_socket_t s)
+data_available(ftpbuf_t *ftp, php_socket_t s, bool silent)
 {
 	int		n;
 
@@ -1633,6 +1633,9 @@
 	if (n < 1) {
 		char buf[256];
 		if (n == 0) {
+			if (silent) {
+				return 0;
+			}
 #ifdef PHP_WIN32
 			_set_errno(ETIMEDOUT);
 #else
@@ -1961,7 +1964,9 @@
 		done = 0;
 	}
 
-	while (!done && data_available(ftp, fd)) {
+	/* Don't report timeouts on the control channel if we're negotiating a shutdown already.
+	 * Some servers don't put a final response. */
+	while (!done && data_available(ftp, fd, true)) {
 		ERR_clear_error();
 		nread = SSL_read(ssl_handle, buf, sizeof(buf));
 		if (nread <= 0) {
@@ -2219,7 +2224,7 @@
 	data = ftp->data;
 
 	/* check if there is already more data */
-	if (!data_available(ftp, data->fd)) {
+	if (!data_available(ftp, data->fd, false)) {
 		return PHP_FTP_MOREDATA;
 	}
 
diff '--color=auto' -Naur a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c
--- a/ext/ftp/php_ftp.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/ftp/php_ftp.c	2025-11-18 21:43:27.156953327 +0000
@@ -809,7 +809,7 @@
 }
 /* }}} */
 
-/* {{{ Continues retrieving/sending a file nbronously */
+/* {{{ Continues to retrieve or send a file in non-blocking mode */
 PHP_FUNCTION(ftp_nb_continue)
 {
 	zval		*z_ftp;
@@ -822,7 +822,7 @@
 	GET_FTPBUF(ftp, z_ftp);
 
 	if (!ftp->nb) {
-		php_error_docref(NULL, E_WARNING, "No nbronous transfer to continue");
+		php_error_docref(NULL, E_WARNING, "No non-blocking transfer to continue");
 		RETURN_LONG(PHP_FTP_FAILED);
 	}
 
diff '--color=auto' -Naur a/ext/ftp/tests/005.phpt b/ext/ftp/tests/005.phpt
--- a/ext/ftp/tests/005.phpt	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/ftp/tests/005.phpt	2025-11-18 21:43:27.157413516 +0000
@@ -85,7 +85,7 @@
 Warning: ftp_mkdir(): Command not implemented (7). in %s005.php on line %d
 bool(false)
 
-Warning: ftp_nb_continue(): No nbronous transfer to continue in %s005.php on line %d
+Warning: ftp_nb_continue(): No non-blocking transfer to continue in %s on line %d
 int(0)
 ftp_nb_fget(): Argument #4 ($mode) must be either FTP_ASCII or FTP_BINARY
 ftp_nb_fput(): Argument #4 ($mode) must be either FTP_ASCII or FTP_BINARY
diff '--color=auto' -Naur a/ext/gd/gd.c b/ext/gd/gd.c
--- a/ext/gd/gd.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/gd/gd.c	2025-11-18 21:43:27.157565789 +0000
@@ -3732,9 +3732,11 @@
 		RETURN_THROWS();
 	}
 
-	if (filtertype >= 0 && filtertype <= IMAGE_FILTER_MAX) {
-		filters[filtertype](INTERNAL_FUNCTION_PARAM_PASSTHRU);
+	if (UNEXPECTED(filtertype < 0 || filtertype > IMAGE_FILTER_MAX)) {
+		zend_argument_value_error(2, "must be one of the IMG_FILTER_* filter constants");
+		RETURN_THROWS();
 	}
+	filters[filtertype](INTERNAL_FUNCTION_PARAM_PASSTHRU);
 }
 /* }}} */
 
diff '--color=auto' -Naur a/ext/gd/tests/gh19955.phpt b/ext/gd/tests/gh19955.phpt
--- a/ext/gd/tests/gh19955.phpt	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/gd/tests/gh19955.phpt	2025-11-18 21:43:27.158813219 +0000
@@ -4,6 +4,10 @@
 gd
 --CREDITS--
 YuanchengJiang
+--SKIPIF--
+<?php
+if(!function_exists('imagefttext')) die('skip imagefttext() not available');
+?>
 --FILE--
 <?php
 ini_set('error_reporting', E_ALL&~E_WARNING);
diff '--color=auto' -Naur a/ext/gd/tests/imagefilter_invalid_filter_error.phpt b/ext/gd/tests/imagefilter_invalid_filter_error.phpt
--- a/ext/gd/tests/imagefilter_invalid_filter_error.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/gd/tests/imagefilter_invalid_filter_error.phpt	2025-11-18 21:43:27.159018506 +0000
@@ -0,0 +1,16 @@
+--TEST--
+GH-20070: Testing wrong parameter passing in imagefilter() of GD library
+--EXTENSIONS--
+gd
+--FILE--
+<?php
+$image = imagecreatetruecolor(1, 1);
+
+try {
+    var_dump(imagefilter($image, -1));
+} catch (Throwable $e) {
+    echo $e::class, ': ', $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+ValueError: imagefilter(): Argument #2 ($filter) must be one of the IMG_FILTER_* filter constants
diff '--color=auto' -Naur a/ext/iconv/config.m4 b/ext/iconv/config.m4
--- a/ext/iconv/config.m4	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/iconv/config.m4	2025-11-18 21:43:27.159135457 +0000
@@ -83,6 +83,20 @@
   AS_VAR_IF([php_cv_iconv_errno], [yes],,
     [AC_MSG_FAILURE([The iconv check failed, 'errno' is missing.])])
 
+  dnl iconv on some platforms (NetBSD pre-10, Solaris) may have a non-standard
+  dnl const input parameter; libiconv may imitate this on those platforms.
+  AC_CACHE_CHECK([if iconv input parameter is const (non-standard)], [php_cv_iconv_const],
+    [AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+#include <iconv.h>
+
+size_t iconv(iconv_t cd, const char **src, size_t *srcleft, char **dst, size_t *dstleft);
+    ])],
+    [php_cv_iconv_const=const],
+    [php_cv_iconv_const=non-const])])
+  dnl non-const is just used for display, set it back
+  AS_VAR_IF([php_cv_iconv_const], [non-const],
+    [php_cv_iconv_const=])
+
   AC_CACHE_CHECK([if iconv supports //IGNORE], [php_cv_iconv_ignore],
     [AC_RUN_IFELSE([AC_LANG_SOURCE([
 #include <iconv.h>
@@ -120,7 +134,7 @@
   PHP_NEW_EXTENSION([iconv],
     [iconv.c],
     [$ext_shared],,
-    [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])
+    [-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -DICONV_CONST=$php_cv_iconv_const])
   PHP_SUBST([ICONV_SHARED_LIBADD])
   PHP_INSTALL_HEADERS([ext/iconv], [php_iconv.h])
 fi
diff '--color=auto' -Naur a/ext/iconv/iconv.c b/ext/iconv/iconv.c
--- a/ext/iconv/iconv.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/iconv/iconv.c	2025-11-18 21:43:27.159565815 +0000
@@ -43,11 +43,11 @@
 #undef iconv
 #endif
 
-#if defined(__NetBSD__)
-// unfortunately, netbsd has still the old non posix conformant signature
-// libiconv tends to match the eventual system's iconv too.
-#define ICONV_CONST const
-#else
+/* iconv can have different constiness for src on some platforms;
+ * this is explained in config.m4. On Windows, it's always non-const,
+ * but it can be awkward to set that on the command line. Do it here.
+ */
+#ifndef ICONV_CONST
 #define ICONV_CONST
 #endif
 
diff '--color=auto' -Naur a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c
--- a/ext/intl/locale/locale_methods.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/intl/locale/locale_methods.c	2025-11-18 21:43:27.160336585 +0000
@@ -1290,6 +1290,7 @@
 		/* canonicalize lang_tag */
 		can_lang_tag = get_icu_value_internal( lang_tag , LOC_CANONICALIZE_TAG , &result ,  0);
 		if( result <=0) {
+			zend_string_release_ex( can_loc_range, false );
 			intl_error_set( NULL, status,
 				"locale_filter_matches : unable to canonicalize lang_tag" , 0 );
 			RETURN_FALSE;
diff '--color=auto' -Naur a/ext/libxml/libxml.c b/ext/libxml/libxml.c
--- a/ext/libxml/libxml.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/libxml/libxml.c	2025-11-18 21:43:27.160960713 +0000
@@ -40,6 +40,7 @@
 #ifdef LIBXML_SCHEMAS_ENABLED
 #include <libxml/relaxng.h>
 #include <libxml/xmlschemas.h>
+#include <libxml/xmlschemastypes.h>
 #endif
 
 #include "php_libxml.h"
@@ -929,7 +930,16 @@
 	if (!_php_libxml_initialized) {
 		/* we should be the only one's to ever init!! */
 		ZEND_IGNORE_LEAKS_BEGIN();
+
 		xmlInitParser();
+#ifdef ZTS
+# ifdef LIBXML_SCHEMAS_ENABLED
+		xmlSchemaInitTypes();
+# endif
+# ifdef LIBXML_RELAXNG_ENABLED
+		xmlRelaxNGInitTypes();
+# endif
+#endif
 		ZEND_IGNORE_LEAKS_END();
 
 		_php_libxml_default_entity_loader = xmlGetExternalEntityLoader();
diff '--color=auto' -Naur a/ext/mysqli/tests/bug67563.phpt b/ext/mysqli/tests/bug67563.phpt
--- a/ext/mysqli/tests/bug67563.phpt	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/mysqli/tests/bug67563.phpt	2025-11-18 21:43:27.161579000 +0000
@@ -6,15 +6,12 @@
 <?php
 require_once 'connect.inc';
 
-if ($host !== '127.0.0.1')
-    die('skip local test');
-
 if (@stream_socket_client('udp://[::1]:8888') === false)
-    die('skip no IPv6 support 2');
+    die('skip no IPv6 support');
 
-if (!$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
-    die(sprintf("SKIP Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
-        $host, $user, $db, $port, $socket));
+if (!$link = @my_mysqli_connect('[::1]', $user, $passwd, $db, $port, $socket)) {
+    die(sprintf("SKIP Cannot connect to the server using host=[::1], user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+        $user, $db, $port, $socket));
 }
 ?>
 --INI--
diff '--color=auto' -Naur a/ext/mysqli/tests/mysqli_fetch_field_types.phpt b/ext/mysqli/tests/mysqli_fetch_field_types.phpt
--- a/ext/mysqli/tests/mysqli_fetch_field_types.phpt	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/mysqli/tests/mysqli_fetch_field_types.phpt	2025-11-18 21:43:27.161740395 +0000
@@ -90,6 +90,7 @@
         // MYSQLI_TYPE_GEOMETRY => array('GEOMETRY', 'TODO add testing'),
         MYSQLI_TYPE_NEWDECIMAL => array('DECIMAL', '1.1'),
         MYSQLI_TYPE_BIT => array('BIT', 0),
+        MYSQLI_TYPE_JSON => array('JSON', '[]'),
     );
 
     foreach ($datatypes as $php_type => $datatype) {
diff '--color=auto' -Naur a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c
--- a/ext/mysqlnd/mysqlnd_connection.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/mysqlnd/mysqlnd_connection.c	2025-11-18 21:43:27.161983384 +0000
@@ -557,7 +557,14 @@
 		if (hostname.s[0] != '[' && mysqlnd_fast_is_ipv6_address(hostname.s)) {
 			transport.l = mnd_sprintf(&transport.s, 0, "tcp://[%s]:%u", hostname.s, port);
 		} else {
-			transport.l = mnd_sprintf(&transport.s, 0, "tcp://%s:%u", hostname.s, port);
+			/* Not ipv6, but could already contain a port number, in which case we should not add an extra port.
+			 * See GH-8978. In a port doubling scenario, the first port would be used so we do the same to keep BC. */
+			if (strchr(hostname.s, ':')) {
+				/* TODO: Ideally we should be able to get rid of this workaround in the future. */
+				transport.l = mnd_sprintf(&transport.s, 0, "tcp://%s", hostname.s);
+			} else {
+				transport.l = mnd_sprintf(&transport.s, 0, "tcp://%s:%u", hostname.s, port);
+			}
 		}
 	}
 	DBG_INF_FMT("transport=%s", transport.s? transport.s:"OOM");
diff '--color=auto' -Naur a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
--- a/ext/opcache/ZendAccelerator.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/ZendAccelerator.c	2025-11-18 21:43:27.162777303 +0000
@@ -4443,16 +4443,6 @@
 		}
 	}
 
-	if (EG(zend_constants)) {
-		EG(persistent_constants_count) = EG(zend_constants)->nNumUsed;
-	}
-	if (EG(function_table)) {
-		EG(persistent_functions_count) = EG(function_table)->nNumUsed;
-	}
-	if (EG(class_table)) {
-		EG(persistent_classes_count)   = EG(class_table)->nNumUsed;
-	}
-
 	size_t old_map_ptr_last = CG(map_ptr_last);
 	if (zend_map_ptr_static_last != ZCSG(map_ptr_static_last) || old_map_ptr_last != ZCSG(map_ptr_last)) {
 		CG(map_ptr_last) = ZCSG(map_ptr_last);
@@ -4722,6 +4712,12 @@
 
 		preload_load(orig_map_ptr_static_last);
 
+		/* Update persistent counts, as shutdown will discard anything past
+		 * that, and these tables are aliases to global ones at this point. */
+		EG(persistent_functions_count) = EG(function_table)->nNumUsed;
+		EG(persistent_classes_count)   = EG(class_table)->nNumUsed;
+		EG(persistent_constants_count) = EG(zend_constants)->nNumUsed;
+
 		/* Store individual scripts with unlinked classes */
 		HANDLE_BLOCK_INTERRUPTIONS();
 		SHM_UNPROTECT();
diff '--color=auto' -Naur a/ext/opcache/jit/ir/ir.h b/ext/opcache/jit/ir/ir.h
--- a/ext/opcache/jit/ir/ir.h	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/jit/ir/ir.h	2025-11-18 21:43:27.164218814 +0000
@@ -257,6 +257,8 @@
 	_(UGE,          d2,   def, def, ___) /* unsigned greater or equal   */ \
 	_(ULE,          d2,   def, def, ___) /* unsigned less or equal      */ \
 	_(UGT,          d2,   def, def, ___) /* unsigned greater            */ \
+	_(ORDERED,      d2,   def, def, ___) /* both operands are not NAN   */ \
+	_(UNORDERED,    d2,   def, def, ___) /* one of operands is NAN      */ \
 	\
 	/* arithmetic ops                                                   */ \
 	_(ADD,          d2C,  def, def, ___) /* addition                    */ \
@@ -1032,6 +1034,7 @@
 #define IR_ERROR_UNSUPPORTED_CODE_RULE           3
 #define IR_ERROR_LINK                            4
 #define IR_ERROR_ENCODE                          5
+#define IR_ERROR_TOO_LARGE                       6
 
 /* IR Memmory Allocation */
 #ifndef ir_mem_malloc
diff '--color=auto' -Naur a/ext/opcache/jit/ir/ir_aarch64.dasc b/ext/opcache/jit/ir/ir_aarch64.dasc
--- a/ext/opcache/jit/ir/ir_aarch64.dasc	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/jit/ir/ir_aarch64.dasc	2025-11-18 21:43:27.165565892 +0000
@@ -658,16 +658,35 @@
 			flags = IR_OP2_MUST_BE_IN_REG;
 			constraints->tmp_regs[0] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
 			n = 1;
+			insn = &ctx->ir_base[ref];
+			if (IR_IS_CONST_REF(insn->op2)) {
+				constraints->tmp_regs[1] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
+				n = 2;
+			}
 			break;
 		case IR_VA_ARG:
 			flags = IR_USE_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG;
 			constraints->tmp_regs[0] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_SAVE_SUB_REF);
 			n = 1;
+			insn = &ctx->ir_base[ref];
+			if (IR_IS_CONST_REF(insn->op2)) {
+				constraints->tmp_regs[1] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
+				n = 2;
+			}
 			break;
 		case IR_VA_COPY:
 			flags = IR_OP2_MUST_BE_IN_REG | IR_OP3_MUST_BE_IN_REG;
 			constraints->tmp_regs[0] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
 			n = 1;
+			insn = &ctx->ir_base[ref];
+			if (IR_IS_CONST_REF(insn->op2)) {
+				constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
+				n++;
+			}
+			if (IR_IS_CONST_REF(insn->op3)) {
+				constraints->tmp_regs[n] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
+				n++;
+			}
 			break;
 	}
 	constraints->tmps_count = n;
@@ -728,6 +747,9 @@
 				return IR_CMP_FP;
 			}
 			break;
+		case IR_ORDERED:
+		case IR_UNORDERED:
+			return IR_CMP_FP;
 		case IR_ADD:
 		case IR_SUB:
 			if (IR_IS_TYPE_INT(insn->type)) {
@@ -1024,7 +1046,7 @@
 		case IR_IF:
 			if (!IR_IS_CONST_REF(insn->op2) && ctx->use_lists[insn->op2].count == 1) {
 				op2_insn = &ctx->ir_base[insn->op2];
-				if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UGT) {
+				if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UNORDERED) {
 					if (IR_IS_TYPE_INT(ctx->ir_base[op2_insn->op1].type)) {
 						ctx->rules[insn->op2] = IR_FUSED | IR_CMP_INT;
 						return IR_CMP_AND_BRANCH_INT;
@@ -1047,7 +1069,7 @@
 		case IR_GUARD_NOT:
 			if (!IR_IS_CONST_REF(insn->op2) && ctx->use_lists[insn->op2].count == 1) {
 				op2_insn = &ctx->ir_base[insn->op2];
-				if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UGT
+				if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UNORDERED
 					// TODO: register allocator may clobber operands of CMP before they are used in the GUARD_CMP
 				 && (insn->op2 == ref - 1 ||
 				     (insn->op2 == ctx->prev_ref[ref] - 1
@@ -1091,6 +1113,9 @@
 						ctx->flags2 |= IR_HAS_VA_ARG_GP|IR_HAS_VA_ARG_FP;
 					}
 				}
+			} else {
+				/* va_list may escape */
+				ctx->flags2 |= IR_HAS_VA_ARG_GP|IR_HAS_VA_ARG_FP;
 			}
 			return IR_VA_START;
 		case IR_VA_END:
@@ -2972,6 +2997,12 @@
 		case IR_UGT:
 			|	cset Rw(def_reg), hi
 			break;
+		case IR_ORDERED:
+			|	cset Rw(def_reg), vc
+			break;
+		case IR_UNORDERED:
+			|	cset Rw(def_reg), vs
+			break;
 	}
 	if (IR_REG_SPILLED(ctx->regs[def][0])) {
 		ir_emit_store(ctx, insn->type, def, def_reg);
@@ -3046,7 +3077,7 @@
 	ir_get_true_false_blocks(ctx, b, &true_block, &false_block);
 	if (true_block == next_block) {
 		/* swap to avoid unconditional JMP */
-		if (int_cmp || op == IR_EQ || op == IR_NE) {
+		if (int_cmp || op == IR_EQ || op == IR_NE || op == IR_ORDERED || op == IR_UNORDERED) {
 			op ^= 1; // reverse
 		} else {
 			op ^= 5; // reverse
@@ -3126,6 +3157,11 @@
 			case IR_UGT:
 				|	bhi =>true_block
 				break;
+			case IR_ORDERED:
+				|	bvc =>true_block
+				break;
+			case IR_UNORDERED:
+				|	bvs =>true_block
 //			case IR_ULT: fprintf(stderr, "\tjb .LL%d\n", true_block); break;
 //			case IR_UGE: fprintf(stderr, "\tjae .LL%d\n", true_block); break;
 //			case IR_ULE: fprintf(stderr, "\tjbe .LL%d\n", true_block); break;
@@ -4443,11 +4479,7 @@
 	ir_reg tmp_reg = ctx->regs[def][3];
 	int32_t offset;
 
-	if (ctx->use_lists[def].count == 1) {
-		/* dead load */
-		return;
-	}
-	IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE);
+	IR_ASSERT((def_reg != IR_REG_NONE || ctx->use_lists[def].count == 1) && tmp_reg != IR_REG_NONE);
 	if (op2_reg != IR_REG_NONE) {
 		if (IR_REG_SPILLED(op2_reg)) {
 			op2_reg = IR_REG_NUM(op2_reg);
@@ -4460,10 +4492,12 @@
 		offset = ir_local_offset(ctx, &ctx->ir_base[insn->op2]);
 	}
 	|	ldr Rx(tmp_reg), [Rx(op2_reg), #offset]
-	ir_emit_load_mem(ctx, type, def_reg, IR_MEM_BO(tmp_reg, 0));
+	if (def_reg  != IR_REG_NONE) {
+		ir_emit_load_mem(ctx, type, def_reg, IR_MEM_BO(tmp_reg, 0));
+	}
 	|	add Rx(tmp_reg), Rx(tmp_reg), #IR_MAX(ir_type_size[type], sizeof(void*))
 	|	str Rx(tmp_reg), [Rx(op2_reg), #offset]
-	if (IR_REG_SPILLED(ctx->regs[def][0])) {
+	if (def_reg != IR_REG_NONE && IR_REG_SPILLED(ctx->regs[def][0])) {
 		ir_emit_store(ctx, type, def, def_reg);
 	}
 #else
@@ -4475,11 +4509,7 @@
 	ir_reg tmp_reg = ctx->regs[def][3];
 	int32_t offset;
 
-	if (ctx->use_lists[def].count == 1) {
-		/* dead load */
-		return;
-	}
-	IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE);
+	IR_ASSERT((def_reg != IR_REG_NONE || ctx->use_lists[def].count == 1) && tmp_reg != IR_REG_NONE);
 	if (op2_reg != IR_REG_NONE) {
 		if (IR_REG_SPILLED(op2_reg)) {
 			op2_reg = IR_REG_NUM(op2_reg);
@@ -4498,13 +4528,17 @@
 		|	ldr Rx(IR_REG_INT_TMP), [Rx(op2_reg), #(offset+offsetof(ir_va_list, gr_top))]
 		|	sxtw Rx(tmp_reg), Rw(tmp_reg)
 		|	add Rx(IR_REG_INT_TMP), Rx(tmp_reg), Rx(IR_REG_INT_TMP)
-		|	ldr Rx(def_reg), [Rx(IR_REG_INT_TMP)]
+		if (def_reg  != IR_REG_NONE) {
+			|	ldr Rx(def_reg), [Rx(IR_REG_INT_TMP)]
+		}
 		|	add Rw(tmp_reg), Rw(tmp_reg), #sizeof(void*)
 		|	str Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, gr_offset))]
 		|	b >2
 		|1:
 		|	ldr Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, stack))]
-		|	ldr Rx(def_reg), [Rx(tmp_reg)]
+		if (def_reg  != IR_REG_NONE) {
+			|	ldr Rx(def_reg), [Rx(tmp_reg)]
+		}
 		|	add Rx(tmp_reg), Rx(tmp_reg), #sizeof(void*)
 		|	str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, stack))]
 		|2:
@@ -4515,18 +4549,22 @@
 		|	ldr Rx(IR_REG_INT_TMP), [Rx(op2_reg), #(offset+offsetof(ir_va_list, vr_top))]
 		|	sxtw Rx(tmp_reg), Rw(tmp_reg)
 		|	add Rx(IR_REG_INT_TMP), Rx(tmp_reg), Rx(IR_REG_INT_TMP)
-		|	ldr Rd(def_reg-IR_REG_FP_FIRST), [Rx(IR_REG_INT_TMP)]
+		if (def_reg  != IR_REG_NONE) {
+			|	ldr Rd(def_reg-IR_REG_FP_FIRST), [Rx(IR_REG_INT_TMP)]
+		}
 		|	add Rw(tmp_reg), Rw(tmp_reg), #16
 		|	str Rw(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, vr_offset))]
 		|	b >2
 		|1:
 		|	ldr Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, stack))]
-		|	ldr Rd(def_reg-IR_REG_FP_FIRST), [Rx(tmp_reg)]
+		if (def_reg  != IR_REG_NONE) {
+			|	ldr Rd(def_reg-IR_REG_FP_FIRST), [Rx(tmp_reg)]
+		}
 		|	add Rx(tmp_reg), Rx(tmp_reg), #sizeof(void*)
 		|	str Rx(tmp_reg), [Rx(op2_reg), #(offset+offsetof(ir_va_list, stack))]
 		|2:
 	}
-	if (IR_REG_SPILLED(ctx->regs[def][0])) {
+	if (def_reg != IR_REG_NONE && IR_REG_SPILLED(ctx->regs[def][0])) {
 		ir_emit_store(ctx, type, def, def_reg);
 	}
 #endif
@@ -5359,6 +5397,11 @@
 			case IR_GT:
 				|	bgt &addr
 				break;
+			case IR_ORDERED:
+				|	bvc &addr
+				break;
+			case IR_UNORDERED:
+				|	bvs &addr
 //			case IR_ULT: fprintf(stderr, "\tjb .LL%d\n", true_block); break;
 //			case IR_UGE: fprintf(stderr, "\tjae .LL%d\n", true_block); break;
 //			case IR_ULE: fprintf(stderr, "\tjbe .LL%d\n", true_block); break;
@@ -6143,6 +6186,14 @@
 	dasm_setup(&data.dasm_state, dasm_actions);
 	/* labels for each block + for each constant + rodata label + jmp_table label + for each entry + exit_table label */
 	dasm_growpc(&data.dasm_state, ctx->cfg_blocks_count + 1 + ctx->consts_count + 1 + 1 + 1 + ctx->entries_count + 1);
+	if (data.dasm_state->status != DASM_S_OK) {
+		IR_ASSERT(data.dasm_state->status == DASM_S_NOMEM);
+		dasm_free(&data.dasm_state);
+		ctx->data = NULL;
+		ctx->status = IR_ERROR_TOO_LARGE;
+		return NULL;
+	}
+
 	data.emit_constants = ir_bitset_malloc(ctx->consts_count);
 
 	if (!(ctx->flags & IR_SKIP_PROLOGUE)) {
@@ -6509,12 +6560,20 @@
 		return NULL;
 	}
 
+	if (data.dasm_state->status != DASM_S_OK) {
+		IR_ASSERT(data.dasm_state->status == DASM_S_NOMEM);
+		dasm_free(&data.dasm_state);
+		ctx->data = NULL;
+		ctx->status = IR_ERROR_TOO_LARGE;
+		return NULL;
+	}
+
 	ret = dasm_link(&data.dasm_state, size_ptr);
 	if (ret != DASM_S_OK) {
-		IR_ASSERT(0);
+		IR_ASSERT(ret == DASM_S_NOMEM);
 		dasm_free(&data.dasm_state);
 		ctx->data = NULL;
-		ctx->status = IR_ERROR_LINK;
+		ctx->status = (ret == DASM_S_NOMEM) ? IR_ERROR_TOO_LARGE : IR_ERROR_LINK;
 		return NULL;
 	}
 	size = *size_ptr;
diff '--color=auto' -Naur a/ext/opcache/jit/ir/ir_check.c b/ext/opcache/jit/ir/ir_check.c
--- a/ext/opcache/jit/ir/ir_check.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/jit/ir/ir_check.c	2025-11-18 21:43:27.166635206 +0000
@@ -36,16 +36,46 @@
 	IR_ASSERT((IR_UGT ^ 3) == IR_ULT);
 	IR_ASSERT((IR_ULE ^ 3) == IR_UGE);
 	IR_ASSERT((IR_UGE ^ 3) == IR_ULE);
+	IR_ASSERT((IR_ORDERED ^ 1) == IR_UNORDERED);
 
 	IR_ASSERT(IR_ADD + 1 == IR_SUB);
 }
 
-static bool ir_check_use_list(const ir_ctx *ctx, ir_ref from, ir_ref to)
+typedef struct {
+	ir_arena  *arena;
+	ir_bitset *use_set;
+	ir_bitset *input_set;
+} ir_check_ctx;
+
+static bool ir_check_use_list(ir_check_ctx *check_ctx, const ir_ctx *ctx, ir_ref from, ir_ref to)
 {
 	ir_ref n, *p;
 	ir_use_list *use_list = &ctx->use_lists[from];
 
 	n = use_list->count;
+	if (n > 16) {
+		/* Avoid quadratic complexity by maintaining a temporary bit-set */
+		ir_bitset set;
+
+		if (!check_ctx->use_set || !(set = check_ctx->use_set[from])) {
+			if (!check_ctx->arena) {
+				check_ctx->arena = ir_arena_create(sizeof(ir_arena) +
+					ctx->insns_count * sizeof(ir_bitset) +
+					ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t));
+			}
+			if (!check_ctx->use_set) {
+				check_ctx->use_set = ir_arena_alloc(&check_ctx->arena, ctx->insns_count * sizeof(ir_bitset));
+				memset(check_ctx->use_set, 0, ctx->insns_count * sizeof(ir_bitset));
+			}
+			check_ctx->use_set[from] = set = (ir_bitset)ir_arena_alloc(&check_ctx->arena,
+				ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t));
+			memset(set, 0, ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t));
+			for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
+				ir_bitset_incl(set, *p);
+			}
+		}
+		return ir_bitset_in(set, to);
+	}
 	for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
 		if (*p == to) {
 			return 1;
@@ -54,12 +84,35 @@
 	return 0;
 }
 
-static bool ir_check_input_list(const ir_ctx *ctx, ir_ref from, ir_ref to)
+static bool ir_check_input_list(ir_check_ctx *check_ctx, const ir_ctx *ctx, ir_ref from, ir_ref to)
 {
 	ir_insn *insn = &ctx->ir_base[to];
 	ir_ref n, j, *p;
 
 	n = ir_input_edges_count(ctx, insn);
+	if (n > 16) {
+		/* Avoid quadratic complexity by maintaining a temporary bit-set */
+		ir_bitset set;
+
+		if (!check_ctx->input_set || !(set = check_ctx->input_set[to])) {
+			if (!check_ctx->arena) {
+				check_ctx->arena = ir_arena_create(sizeof(ir_arena) +
+					ctx->insns_count * sizeof(ir_bitset) +
+					ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t));
+			}
+			if (!check_ctx->input_set) {
+				check_ctx->input_set = ir_arena_alloc(&check_ctx->arena, ctx->insns_count * sizeof(ir_bitset));
+				memset(check_ctx->input_set, 0, ctx->insns_count * sizeof(ir_bitset));
+			}
+			check_ctx->input_set[to] = set = (ir_bitset)ir_arena_alloc(&check_ctx->arena,
+				ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t));
+			memset(set, 0, ir_bitset_len(ctx->insns_count) * sizeof(ir_bitset_base_t));
+			for (j = 1, p = insn->ops + 1; j <= n; j++, p++) {
+				if (*p > 0) ir_bitset_incl(set, *p);
+			}
+		}
+		return ir_bitset_in(set, from);
+	}
 	for (j = 1, p = insn->ops + 1; j <= n; j++, p++) {
 		if (*p == from) {
 			return 1;
@@ -93,6 +146,11 @@
 	ir_type type;
 	uint32_t flags;
 	bool ok = 1;
+	ir_check_ctx check_ctx;
+
+	check_ctx.arena = NULL;
+	check_ctx.use_set = NULL;
+	check_ctx.input_set = NULL;
 
 	for (i = IR_UNUSED + 1, insn = ctx->ir_base + i; i < ctx->insns_count;) {
 		if (insn->op >= IR_LAST_OP) {
@@ -255,7 +313,7 @@
 			}
 			if (ctx->use_lists
 			 && use > 0
-			 && !ir_check_use_list(ctx, use, i)) {
+			 && !ir_check_use_list(&check_ctx, ctx, use, i)) {
 				fprintf(stderr, "ir_base[%d].ops[%d] is not in use list (%d)\n", i, j, use);
 				ok = 0;
 			}
@@ -313,7 +371,7 @@
 
 			for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
 				use = *p;
-				if (!ir_check_input_list(ctx, i, use)) {
+				if (!ir_check_input_list(&check_ctx, ctx, i, use)) {
 					fprintf(stderr, "ir_base[%d] is in use list of ir_base[%d]\n", use, i);
 					ok = 0;
 				}
@@ -393,6 +451,10 @@
 		insn += n;
 	}
 
+	if (check_ctx.arena) {
+		ir_arena_free(check_ctx.arena);
+	}
+
 //	if (!ok) {
 //		ir_dump_codegen(ctx, stderr);
 //	}
diff '--color=auto' -Naur a/ext/opcache/jit/ir/ir_emit.c b/ext/opcache/jit/ir/ir_emit.c
--- a/ext/opcache/jit/ir/ir_emit.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/jit/ir/ir_emit.c	2025-11-18 21:43:27.166997079 +0000
@@ -32,8 +32,14 @@
   do { \
     size_t _sz = (sz), _need = (need); \
     if (_sz < _need) { \
+      size_t _limit = sizeof(t) * DASM_SEC2POS(1); \
+      if (_need > _limit) { \
+        Dst_REF->status = DASM_S_NOMEM; \
+        return; \
+      } \
       if (_sz < 16) _sz = 16; \
       while (_sz < _need) _sz += _sz; \
+      if (_sz > _limit) _sz = _limit; \
       (p) = (t *)ir_mem_realloc((p), _sz); \
       (sz) = _sz; \
     } \
diff '--color=auto' -Naur a/ext/opcache/jit/ir/ir_fold.h b/ext/opcache/jit/ir/ir_fold.h
--- a/ext/opcache/jit/ir/ir_fold.h	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/jit/ir/ir_fold.h	2025-11-18 21:43:27.167565918 +0000
@@ -274,6 +274,106 @@
 	IR_FOLD_BOOL(!(op1_insn->val.f <= op2_insn->val.f));
 }
 
+IR_FOLD(ORDERED(C_FLOAT, C_FLOAT))
+{
+	IR_FOLD_BOOL(!isnan(op1_insn->val.f) && !isnan(op2_insn->val.f));
+}
+
+IR_FOLD(ORDERED(C_DOUBLE, C_DOUBLE))
+{
+	IR_FOLD_BOOL(!isnan(op1_insn->val.d) && !isnan(op2_insn->val.d));
+}
+
+IR_FOLD(UNORDERED(C_FLOAT, C_FLOAT))
+{
+	IR_FOLD_BOOL(isnan(op1_insn->val.f) || isnan(op2_insn->val.f));
+}
+
+IR_FOLD(UNORDERED(C_DOUBLE, C_DOUBLE))
+{
+	IR_FOLD_BOOL(isnan(op1_insn->val.d) || isnan(op2_insn->val.d));
+}
+
+IR_FOLD(EQ(_, C_FLOAT))
+IR_FOLD(LT(_, C_FLOAT))
+IR_FOLD(GE(_, C_FLOAT))
+IR_FOLD(LE(_, C_FLOAT))
+IR_FOLD(GT(_, C_FLOAT))
+{
+	if (isnan(op2_insn->val.f)) {
+		IR_FOLD_COPY(IR_FALSE);
+	}
+	IR_FOLD_NEXT;
+}
+
+IR_FOLD(NE(_, C_FLOAT))
+{
+	if (isnan(op2_insn->val.f)) {
+		IR_FOLD_COPY(IR_TRUE);
+	}
+	IR_FOLD_NEXT;
+}
+
+IR_FOLD(ORDERED(_, C_FLOAT))
+{
+	if (isnan(op2_insn->val.f)) {
+		IR_FOLD_COPY(IR_FALSE);
+	} else {
+		op2 = op1;
+		IR_FOLD_RESTART;
+	}
+}
+
+IR_FOLD(UNORDERED(_, C_FLOAT))
+{
+	if (isnan(op2_insn->val.f)) {
+		IR_FOLD_COPY(IR_TRUE);
+	} else {
+		op2 = op1;
+		IR_FOLD_RESTART;
+	}
+}
+
+IR_FOLD(EQ(_, C_DOUBLE))
+IR_FOLD(LT(_, C_DOUBLE))
+IR_FOLD(GE(_, C_DOUBLE))
+IR_FOLD(LE(_, C_DOUBLE))
+IR_FOLD(GT(_, C_DOUBLE))
+{
+	if (isnan(op2_insn->val.d)) {
+		IR_FOLD_COPY(IR_FALSE);
+	}
+	IR_FOLD_NEXT;
+}
+
+IR_FOLD(NE(_, C_DOUBLE))
+{
+	if (isnan(op2_insn->val.d)) {
+		IR_FOLD_COPY(IR_TRUE);
+	}
+	IR_FOLD_NEXT;
+}
+
+IR_FOLD(ORDERED(_, C_DOUBLE))
+{
+	if (isnan(op2_insn->val.d)) {
+		IR_FOLD_COPY(IR_FALSE);
+	} else {
+		op2 = op1;
+		IR_FOLD_RESTART;
+	}
+}
+
+IR_FOLD(UNORDERED(_, C_DOUBLE))
+{
+	if (isnan(op2_insn->val.d)) {
+		IR_FOLD_COPY(IR_TRUE);
+	} else {
+		op2 = op1;
+		IR_FOLD_RESTART;
+	}
+}
+
 IR_FOLD(ADD(C_U8, C_U8))
 {
 	IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type);
@@ -538,7 +638,8 @@
 IR_FOLD(DIV(C_I8, C_I8))
 {
 	IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type);
-	if (op2_insn->val.i64 == 0) {
+	if (op2_insn->val.i64 == 0
+	 || (op2_insn->val.i64 == -1 && op1_insn->val.u8 == 0x80)) {
 		/* division by zero */
 		IR_FOLD_EMIT;
 	}
@@ -548,7 +649,8 @@
 IR_FOLD(DIV(C_I16, C_I16))
 {
 	IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type);
-	if (op2_insn->val.i64 == 0) {
+	if (op2_insn->val.i64 == 0
+	 || (op2_insn->val.i64 == -1 && op1_insn->val.u16 == 0x8000)) {
 		/* division by zero */
 		IR_FOLD_EMIT;
 	}
@@ -558,7 +660,8 @@
 IR_FOLD(DIV(C_I32, C_I32))
 {
 	IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type);
-	if (op2_insn->val.i64 == 0) {
+	if (op2_insn->val.i64 == 0
+	 || (op2_insn->val.i64 == -1 && op1_insn->val.u32 == 0x80000000)) {
 		/* division by zero */
 		IR_FOLD_EMIT;
 	}
@@ -568,7 +671,8 @@
 IR_FOLD(DIV(C_I64, C_I64))
 {
 	IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type);
-	if (op2_insn->val.i64 == 0) {
+	if (op2_insn->val.i64 == 0
+	 || (op2_insn->val.i64 == -1 && op1_insn->val.u64 == 0x8000000000000000)) {
 		/* division by zero */
 		IR_FOLD_EMIT;
 	}
@@ -615,12 +719,27 @@
 }
 
 IR_FOLD(NEG(C_I8))
+{
+	IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type);
+	IR_FOLD_CONST_I((int8_t)(0 - op1_insn->val.u8));
+}
+
 IR_FOLD(NEG(C_I16))
+{
+	IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type);
+	IR_FOLD_CONST_I((int16_t)(0 -op1_insn->val.u16));
+}
+
 IR_FOLD(NEG(C_I32))
+{
+	IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type);
+	IR_FOLD_CONST_I((int32_t)(0 - op1_insn->val.u32));
+}
+
 IR_FOLD(NEG(C_I64))
 {
 	IR_ASSERT(IR_OPT_TYPE(opt) == op1_insn->type);
-	IR_FOLD_CONST_I(-op1_insn->val.u64);
+	IR_FOLD_CONST_I(0 - op1_insn->val.u64);
 }
 
 IR_FOLD(NEG(C_DOUBLE))
@@ -1626,6 +1745,8 @@
 IR_FOLD(NOT(UGE))
 IR_FOLD(NOT(ULE))
 IR_FOLD(NOT(UGT))
+IR_FOLD(NOT(ORDERED))
+IR_FOLD(NOT(UNORDERED))
 {
 	if (IR_IS_TYPE_INT(ctx->ir_base[op1_insn->op1].type)) {
 		opt = op1_insn->opt ^ 1;
@@ -1841,6 +1962,12 @@
 	if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt))) {
 		if (op1_insn->op2 == op2) {
 			/* (a - b) + b => a */
+			if (ctx->ir_base[op1_insn->op1].type != IR_OPT_TYPE(opt)) {
+				opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK);
+				op1 = op1_insn->op1;
+				op2 = IR_UNUSED;
+				IR_FOLD_RESTART;
+			}
 			IR_FOLD_COPY(op1_insn->op1);
 		}
 	}
@@ -1852,6 +1979,12 @@
 	if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt))) {
 		if (op2_insn->op2 == op1) {
 			/* a + (b - a) => b */
+			if (ctx->ir_base[op2_insn->op1].type != IR_OPT_TYPE(opt)) {
+				opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK);
+				op1 = op2_insn->op1;
+				op2 = IR_UNUSED;
+				IR_FOLD_RESTART;
+			}
 			IR_FOLD_COPY(op2_insn->op1);
 		}
 	}
@@ -1863,9 +1996,21 @@
 	if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt))) {
 		if (op1_insn->op1 == op2) {
 			/* (a + b) - a => b */
+			if (ctx->ir_base[op1_insn->op2].type != IR_OPT_TYPE(opt)) {
+				opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK);
+				op1 = op1_insn->op2;
+				op2 = IR_UNUSED;
+				IR_FOLD_RESTART;
+			}
 			IR_FOLD_COPY(op1_insn->op2);
 		} else if (op1_insn->op2 == op2) {
 			/* (a + b) - a => b */
+			if (ctx->ir_base[op1_insn->op1].type != IR_OPT_TYPE(opt)) {
+				opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK);
+				op1 = op1_insn->op1;
+				op2 = IR_UNUSED;
+				IR_FOLD_RESTART;
+			}
 			IR_FOLD_COPY(op1_insn->op1);
 		}
 	}
@@ -1911,6 +2056,12 @@
 	if (IR_IS_TYPE_INT(IR_OPT_TYPE(opt))) {
 		if (op2_insn->op1 == op1) {
 			/* a - (a - b) => b */
+			if (ctx->ir_base[op2_insn->op2].type != IR_OPT_TYPE(opt)) {
+				opt = IR_BITCAST | (opt & IR_OPT_TYPE_MASK);
+				op1 = op2_insn->op2;
+				op2 = IR_UNUSED;
+				IR_FOLD_RESTART;
+			}
 			IR_FOLD_COPY(op2_insn->op2);
 		}
 	}
@@ -3133,6 +3284,8 @@
 
 /* Swap operands (move lower ref to op2) for better CSE */
 IR_FOLD(MUL(_, _))
+IR_FOLD(ORDERED(_, _))
+IR_FOLD(UNORDERED(_, _))
 IR_FOLD_NAMED(swap_ops)
 {
 	if (op1 < op2) {  /* move lower ref to op2 */
diff '--color=auto' -Naur a/ext/opcache/jit/ir/ir_gcm.c b/ext/opcache/jit/ir/ir_gcm.c
--- a/ext/opcache/jit/ir/ir_gcm.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/jit/ir/ir_gcm.c	2025-11-18 21:43:27.168476112 +0000
@@ -1379,6 +1379,8 @@
 					switch (new_insn->op) {
 						case IR_EQ:
 						case IR_NE:
+						case IR_ORDERED:
+						case IR_UNORDERED:
 						case IR_ADD:
 						case IR_MUL:
 						case IR_ADD_OV:
diff '--color=auto' -Naur a/ext/opcache/jit/ir/ir_private.h b/ext/opcache/jit/ir/ir_private.h
--- a/ext/opcache/jit/ir/ir_private.h	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/jit/ir/ir_private.h	2025-11-18 21:43:27.169012394 +0000
@@ -238,6 +238,7 @@
 
 	IR_ASSERT(size >= IR_ALIGNED_SIZE(sizeof(ir_arena), 8));
 	arena = (ir_arena*)ir_mem_malloc(size);
+	if (UNEXPECTED(!arena))return NULL;
 	arena->ptr = (char*) arena + IR_ALIGNED_SIZE(sizeof(ir_arena), 8);
 	arena->end = (char*) arena + size;
 	arena->prev = NULL;
@@ -267,6 +268,7 @@
 				(size_t)(arena->end - (char*) arena);
 		ir_arena *new_arena = (ir_arena*)ir_mem_malloc(arena_size);
 
+		if (UNEXPECTED(!new_arena)) return NULL;
 		ptr = (char*) new_arena + IR_ALIGNED_SIZE(sizeof(ir_arena), 8);
 		new_arena->ptr = (char*) new_arena + IR_ALIGNED_SIZE(sizeof(ir_arena), 8) + size;
 		new_arena->end = (char*) new_arena + arena_size;
diff '--color=auto' -Naur a/ext/opcache/jit/ir/ir_sccp.c b/ext/opcache/jit/ir/ir_sccp.c
--- a/ext/opcache/jit/ir/ir_sccp.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/jit/ir/ir_sccp.c	2025-11-18 21:43:27.169565944 +0000
@@ -12,6 +12,8 @@
 #include "ir.h"
 #include "ir_private.h"
 
+#include <math.h>
+
 #define IR_COMBO_COPY_PROPAGATION 1
 
 #define IR_TOP                  IR_UNUSED
@@ -420,11 +422,12 @@
 static bool ir_is_dead_load(ir_ctx *ctx, ir_ref ref)
 {
 	if (ctx->use_lists[ref].count == 1) {
-		uint32_t flags = ir_op_flags[ctx->ir_base[ref].op];
+		ir_insn *insn = &ctx->ir_base[ref];
+		uint32_t flags = ir_op_flags[insn->op];
 
 		if ((flags & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)) {
 			return 1;
-		} else if (ctx->ir_base[ref].op == IR_ALLOCA) {
+		} else if (insn->op == IR_ALLOCA || insn->op == IR_BLOCK_BEGIN) {
 			return 1;
 		}
 	}
@@ -583,6 +586,15 @@
 				}
 			} else {
 				IR_MAKE_BOTTOM_EX(i);
+				n = IR_INPUT_EDGES_COUNT(flags);
+				for (p = insn->ops + 1; n > 0; p++, n--) {
+					ir_ref input = *p;
+					if (input > 0) {
+						if (_values[input].op == IR_TOP) {
+							ir_sccp_add_input(ctx, _values, worklist, input);
+						}
+					}
+				}
 			}
 		} else if (flags & IR_OP_FLAG_BB_START) {
 			if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN || insn->op == IR_BEGIN) {
@@ -717,52 +729,32 @@
 				ir_bitqueue_add(iter_worklist, i);
 				IR_MAKE_BOTTOM(i);
 			} else {
-				if (_values[i].op == IR_TOP) {
-					bool has_top = 0;
-
-					/* control, call, load and store instructions may have unprocessed inputs */
-					n = IR_INPUT_EDGES_COUNT(flags);
-					if (IR_OP_HAS_VAR_INPUTS(flags) && (n = insn->inputs_count) > 3) {
-						for (j = 0; j < (n>>2); j++) {
-							_values[i+j+1].optx = IR_BOTTOM; /* keep the tail of a long multislot instruction */
-						}
-						for (j = 2, p = insn->ops + j; j <= n; j++, p++) {
-							IR_ASSERT(IR_OPND_KIND(flags, j) == IR_OPND_DATA);
-							use = *p;
-							if (use > 0 && _values[use].op == IR_TOP) {
-								has_top = 1;
-								ir_sccp_add_input(ctx, _values, worklist, use);
-							}
-						}
-					} else if (n >= 2) {
-						IR_ASSERT(IR_OPND_KIND(flags, 2) == IR_OPND_DATA);
-						use = insn->op2;
+				/* control, call, load and store instructions may have unprocessed inputs */
+				n = IR_INPUT_EDGES_COUNT(flags);
+				if (IR_OP_HAS_VAR_INPUTS(flags) && (n = insn->inputs_count) > 3) {
+					for (j = 0; j < (n>>2); j++) {
+						_values[i+j+1].optx = IR_BOTTOM; /* keep the tail of a long multislot instruction */
+					}
+					for (j = 2, p = insn->ops + j; j <= n; j++, p++) {
+						IR_ASSERT(IR_OPND_KIND(flags, j) == IR_OPND_DATA);
+						use = *p;
 						if (use > 0 && _values[use].op == IR_TOP) {
-							has_top = 1;
 							ir_sccp_add_input(ctx, _values, worklist, use);
 						}
-						if (n > 2) {
-							IR_ASSERT(n == 3);
-							IR_ASSERT(IR_OPND_KIND(flags, 3) == IR_OPND_DATA);
-							use = insn->op3;
-							if (use > 0 && _values[use].op == IR_TOP) {
-								has_top = 1;
-								ir_sccp_add_input(ctx, _values, worklist, use);
-							}
-						}
 					}
-
-					if (has_top && !(flags & IR_OP_FLAG_BB_END)) {
-						use = ir_next_control(ctx, i);
-						if (_values[use].op == IR_TOP) {
-							has_top = 1;
-							/* do forward control propagaton only once */
-							if (!_values[use].op1) {
-								_values[use].op1 = 1;
-								ir_bitqueue_add(worklist, use);
-							}
+				} else if (n >= 2) {
+					IR_ASSERT(IR_OPND_KIND(flags, 2) == IR_OPND_DATA);
+					use = insn->op2;
+					if (use > 0 && _values[use].op == IR_TOP) {
+						ir_sccp_add_input(ctx, _values, worklist, use);
+					}
+					if (n > 2) {
+						IR_ASSERT(n == 3);
+						IR_ASSERT(IR_OPND_KIND(flags, 3) == IR_OPND_DATA);
+						use = insn->op3;
+						if (use > 0 && _values[use].op == IR_TOP) {
+							ir_sccp_add_input(ctx, _values, worklist, use);
 						}
-						continue;
 					}
 				}
 				IR_MAKE_BOTTOM(i);
@@ -1325,8 +1317,8 @@
 			}
 		}
 	 } else if (n < 2) {
-		IR_ASSERT(n == 1);
-		if (!IR_IS_CONST_REF(op1)) {
+		if (op1 > 0) {
+			IR_ASSERT(n == 1);
 			use_list = &ctx->use_lists[op1];
 			n = use_list->count;
 			for (p = ctx->use_edges + use_list->refs; n > 0; p++, n--) {
@@ -2819,6 +2811,10 @@
 			return !(op1->val.d > op2->val.d);
 		} else if (op == IR_UGT) {
 			return !(op1->val.d <= op2->val.d);
+		} else if (op == IR_ORDERED) {
+			return !isnan(op1->val.d) && !isnan(op2->val.d);
+		} else if (op == IR_UNORDERED) {
+			return isnan(op1->val.d) || isnan(op2->val.d);
 		} else {
 			IR_ASSERT(0);
 			return 0;
@@ -2845,6 +2841,10 @@
 			return !(op1->val.f > op2->val.f);
 		} else if (op == IR_UGT) {
 			return !(op1->val.f <= op2->val.f);
+		} else if (op == IR_ORDERED) {
+			return !isnan(op1->val.f) && !isnan(op2->val.f);
+		} else if (op == IR_UNORDERED) {
+			return isnan(op1->val.f) || isnan(op2->val.f);
 		} else {
 			IR_ASSERT(0);
 			return 0;
@@ -3476,9 +3476,18 @@
 remove_guard:
 				prev = insn->op1;
 				next = ir_next_control(ctx, ref);
+				if (ctx->ir_base[prev].op == IR_SNAPSHOT) {
+					ir_ref snapshot = prev;
+					prev = ctx->ir_base[prev].op1;
+					ir_use_list_remove_one(ctx, snapshot, ref);
+					ir_use_list_remove_one(ctx, ref, next);
+					ir_use_list_replace_one(ctx, prev, snapshot, next);
+					ir_iter_remove_insn(ctx, snapshot, worklist);
+				} else {
+					ir_use_list_remove_one(ctx, ref, next);
+					ir_use_list_replace_one(ctx, prev, ref, next);
+				}
 				ctx->ir_base[next].op1 = prev;
-				ir_use_list_remove_one(ctx, ref, next);
-				ir_use_list_replace_one(ctx, prev, ref, next);
 				insn->op1 = IR_UNUSED;
 
 				if (!IR_IS_CONST_REF(insn->op2)) {
@@ -3489,9 +3498,12 @@
 					}
 				}
 
-				if (insn->op3) {
-					/* SNAPSHOT */
-					ir_iter_remove_insn(ctx, insn->op3, worklist);
+				if (!IR_IS_CONST_REF(insn->op3)) {
+					ir_use_list_remove_one(ctx, insn->op3, ref);
+					if (ir_is_dead(ctx, insn->op3)) {
+						/* schedule DCE */
+						ir_bitqueue_add(worklist, insn->op3);
+					}
 				}
 
 				MAKE_NOP(insn);
diff '--color=auto' -Naur a/ext/opcache/jit/ir/ir_x86.dasc b/ext/opcache/jit/ir/ir_x86.dasc
--- a/ext/opcache/jit/ir/ir_x86.dasc	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/jit/ir/ir_x86.dasc	2025-11-18 21:43:27.172565983 +0000
@@ -1238,6 +1238,9 @@
 			if (IR_IS_CONST_REF(insn->op2) && insn->op1 != insn->op2) {
 				constraints->tmp_regs[n] = IR_TMP_REG(2, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
 				n++;
+			} else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) {
+				constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
+				n = 1;
 			}
 			break;
 		case IR_CMP_INT:
@@ -1564,16 +1567,35 @@
 			flags = IR_OP2_MUST_BE_IN_REG;
 			constraints->tmp_regs[0] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
 			n = 1;
+			insn = &ctx->ir_base[ref];
+			if (IR_IS_CONST_REF(insn->op2)) {
+				constraints->tmp_regs[1] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
+				n = 2;
+			}
 			break;
 		case IR_VA_ARG:
 			flags = IR_USE_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG;
 			constraints->tmp_regs[0] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_SAVE_SUB_REF);
 			n = 1;
+			insn = &ctx->ir_base[ref];
+			if (IR_IS_CONST_REF(insn->op2)) {
+				constraints->tmp_regs[1] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
+				n = 2;
+			}
 			break;
 		case IR_VA_COPY:
 			flags = IR_OP2_MUST_BE_IN_REG | IR_OP3_MUST_BE_IN_REG;
 			constraints->tmp_regs[0] = IR_TMP_REG(1, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
 			n = 1;
+			insn = &ctx->ir_base[ref];
+			if (IR_IS_CONST_REF(insn->op2)) {
+				constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
+				n++;
+			}
+			if (IR_IS_CONST_REF(insn->op3)) {
+				constraints->tmp_regs[n] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
+				n++;
+			}
 			break;
 		case IR_SSE_SQRT:
 		case IR_SSE_RINT:
@@ -1859,7 +1881,8 @@
 		/* pass */
 	} else if ((IR_IS_CONST_REF(insn->op1) && !IR_IS_FP_ZERO(ctx->ir_base[insn->op1])) || ir_match_try_fuse_load(ctx, insn->op1, root)) {
 		ir_swap_ops(insn);
-		if (insn->op != IR_EQ && insn->op != IR_NE) {
+		if (insn->op != IR_EQ && insn->op != IR_NE
+		 && insn->op != IR_ORDERED && insn->op != IR_UNORDERED) {
 			insn->op ^= 3;
 		}
 	}
@@ -1886,7 +1909,8 @@
 		/* pass */
 	} else if ((IR_IS_CONST_REF(insn->op1) && !IR_IS_FP_ZERO(ctx->ir_base[insn->op1])) || ir_match_try_fuse_load(ctx, insn->op1, root)) {
 		ir_swap_ops(insn);
-		if (insn->op != IR_EQ && insn->op != IR_NE) {
+		if (insn->op != IR_EQ && insn->op != IR_NE
+		 && insn->op != IR_ORDERED && insn->op != IR_UNORDERED) {
 			insn->op ^= 3;
 		}
 	}
@@ -2013,6 +2037,10 @@
 				return IR_CMP_FP;
 			}
 			break;
+		case IR_ORDERED:
+		case IR_UNORDERED:
+			ir_match_fuse_load_cmp_fp(ctx, insn, ref);
+			return IR_CMP_FP;
 		case IR_ADD:
 		case IR_SUB:
 			if (IR_IS_TYPE_INT(insn->type)) {
@@ -2672,7 +2700,7 @@
 		case IR_IF:
 			if (!IR_IS_CONST_REF(insn->op2) && ctx->use_lists[insn->op2].count == 1) {
 				op2_insn = &ctx->ir_base[insn->op2];
-				if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UGT) {
+				if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UNORDERED) {
 					if (IR_IS_TYPE_INT(ctx->ir_base[op2_insn->op1].type)) {
 						if (IR_IS_CONST_REF(op2_insn->op2)
 						 && !IR_IS_SYM_CONST(ctx->ir_base[op2_insn->op2].op)
@@ -2801,7 +2829,7 @@
 			if (!IR_IS_CONST_REF(insn->op1) && ctx->use_lists[insn->op1].count == 1) {
 				ir_insn *op1_insn = &ctx->ir_base[insn->op1];
 
-				if (op1_insn->op >= IR_EQ && op1_insn->op <= IR_UGT) {
+				if (op1_insn->op >= IR_EQ && op1_insn->op <= IR_UNORDERED) {
 					if (IR_IS_TYPE_INT(ctx->ir_base[op1_insn->op1].type)) {
 						ir_match_fuse_load_cmp_int(ctx, op1_insn, ref);
 						ctx->rules[insn->op1] = IR_FUSED | IR_CMP_INT;
@@ -2818,7 +2846,7 @@
 		case IR_GUARD_NOT:
 			if (!IR_IS_CONST_REF(insn->op2) && ctx->use_lists[insn->op2].count == 1) {
 				op2_insn = &ctx->ir_base[insn->op2];
-				if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UGT
+				if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UNORDERED
 					// TODO: register allocator may clobber operands of CMP before they are used in the GUARD_CMP
 				 && (insn->op2 == ref - 1 ||
 				     (insn->op2 == ctx->prev_ref[ref] - 1
@@ -2971,6 +2999,9 @@
 						ctx->flags2 |= IR_HAS_VA_ARG_GP|IR_HAS_VA_ARG_FP;
 					}
 				}
+			} else {
+				/* va_list may escape */
+				ctx->flags2 |= IR_HAS_VA_ARG_GP|IR_HAS_VA_ARG_FP;
 			}
 			return IR_VA_START;
 		case IR_VA_END:
@@ -3573,7 +3604,13 @@
 		case IR_LEA_B_SI_O:
 			offset_insn = insn;
 			op1_insn = &ctx->ir_base[insn->op1];
-			base_reg_ref = insn->op1 * sizeof(ir_ref) + 1;
+			if (ir_rule(ctx, op1_insn->op1) == IR_STATIC_ALLOCA) {
+				offset = ir_local_offset(ctx, &ctx->ir_base[op1_insn->op1]);
+				base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
+				base_reg_ref = IR_UNUSED;
+			} else {
+				base_reg_ref = insn->op1 * sizeof(ir_ref) + 1;
+			}
 			index_reg_ref = op1_insn->op2 * sizeof(ir_ref) + 1;
 			op2_insn = &ctx->ir_base[op1_insn->op2];
 			scale = ctx->ir_base[op2_insn->op2].val.i32;
@@ -3582,7 +3619,13 @@
 			offset_insn = insn;
 			op1_insn = &ctx->ir_base[insn->op1];
 			index_reg_ref = op1_insn->op1 * sizeof(ir_ref) + 1;
-			base_reg_ref = insn->op1 * sizeof(ir_ref) + 2;
+			if (ir_rule(ctx, op1_insn->op2) == IR_STATIC_ALLOCA) {
+				offset = ir_local_offset(ctx, &ctx->ir_base[op1_insn->op2]);
+				base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
+				base_reg_ref = IR_UNUSED;
+			} else {
+				base_reg_ref = insn->op1 * sizeof(ir_ref) + 2;
+			}
 			op1_insn = &ctx->ir_base[op1_insn->op1];
 			scale = ctx->ir_base[op1_insn->op2].val.i32;
 			break;
@@ -3620,7 +3663,7 @@
 			offset += (int64_t)(intptr_t)(addr);
 		} else {
 			if (offset_insn->op == IR_SUB) {
-				offset = -addr_insn->val.i32;
+				offset -= addr_insn->val.i32;
 			} else {
 				offset += addr_insn->val.i32;
 			}
@@ -6153,6 +6196,12 @@
 			|	mov Rd(tmp_reg), 1
 			|	cmova Rd(def_reg), Rd(tmp_reg)
 			break;
+		case IR_ORDERED:
+			|	setnp Rb(def_reg)
+			break;
+		case IR_UNORDERED:
+			|	setp Rb(def_reg)
+			break;
 	}
 	if (IR_REG_SPILLED(ctx->regs[def][0])) {
 		ir_emit_store(ctx, insn->type, def, def_reg);
@@ -6192,7 +6241,7 @@
 	ir_get_true_false_blocks(ctx, b, &true_block, &false_block);
 	if (true_block == next_block) {
 		/* swap to avoid unconditional JMP */
-		if (int_cmp || op == IR_EQ || op == IR_NE) {
+		if (int_cmp || op == IR_EQ || op == IR_NE || op == IR_ORDERED || op == IR_UNORDERED) {
 			op ^= 1; // reverse
 		} else {
 			op ^= 5; // reverse
@@ -6304,6 +6353,12 @@
 				|	jp =>true_block
 				|	ja =>true_block
 				break;
+			case IR_ORDERED:
+				|	jnp =>true_block
+				break;
+			case IR_UNORDERED:
+				|	jp =>true_block
+				break;
 		}
 	}
 	if (false_block) {
@@ -6822,6 +6877,12 @@
 			|	jp >1
 			|	jbe >2
 			break;
+		case IR_ORDERED:
+			|	jp >2
+			break;
+		case IR_UNORDERED:
+			|	jnp >2
+			break;
 	}
 	|1:
 
@@ -8502,11 +8563,7 @@
 	ir_reg tmp_reg = ctx->regs[def][3];
 	int32_t offset;
 
-	if (ctx->use_lists[def].count == 1) {
-		/* dead load */
-		return;
-	}
-	IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE);
+	IR_ASSERT((def_reg != IR_REG_NONE || ctx->use_lists[def].count == 1) && tmp_reg != IR_REG_NONE);
 	if (op2_reg != IR_REG_NONE) {
 		if (IR_REG_SPILLED(op2_reg)) {
 			op2_reg = IR_REG_NUM(op2_reg);
@@ -8520,27 +8577,34 @@
 	}
 	|	mov Ra(tmp_reg), aword [Ra(op2_reg)+offset]
 #ifdef _WIN64
-	ir_emit_load_mem(ctx, type, def_reg, IR_MEM_B(tmp_reg));
+	if (def_reg != IR_REG_NONE) {
+		ir_emit_load_mem(ctx, type, def_reg, IR_MEM_B(tmp_reg));
+	}
 	|	add Ra(tmp_reg), IR_MAX(ir_type_size[type], sizeof(void*))
 #else
 	if (!insn->op3) {
-		ir_emit_load_mem(ctx, type, def_reg, IR_MEM_B(tmp_reg));
+		if (def_reg != IR_REG_NONE) {
+			ir_emit_load_mem(ctx, type, def_reg, IR_MEM_B(tmp_reg));
+		}
 		|	add Ra(tmp_reg), IR_MAX(ir_type_size[type], sizeof(void*))
 	} else {
-		IR_ASSERT(type == IR_ADDR);
-		int align = 1U << (insn->op3 & 0x7);
 		int size = (uint32_t)insn->op3 >> 3;
 
-		if (align > (int)sizeof(void*)) {
-			|	add Ra(tmp_reg), (align-1)
-			|	and Ra(tmp_reg), ~(align-1)
+		if (def_reg != IR_REG_NONE) {
+			IR_ASSERT(type == IR_ADDR);
+			int align = 1U << (insn->op3 & 0x7);
+
+			if (align > (int)sizeof(void*)) {
+				|	add Ra(tmp_reg), (align-1)
+				|	and Ra(tmp_reg), ~(align-1)
+			}
+			|	mov Ra(def_reg), Ra(tmp_reg)
 		}
-		|	mov Ra(def_reg), Ra(tmp_reg)
 		|	add Ra(tmp_reg), IR_ALIGNED_SIZE(size, sizeof(void*))
 	}
 #endif
 	|	mov aword [Ra(op2_reg)+offset], Ra(tmp_reg)
-	if (IR_REG_SPILLED(ctx->regs[def][0])) {
+	if (def_reg && IR_REG_SPILLED(ctx->regs[def][0])) {
 		ir_emit_store(ctx, type, def, def_reg);
 	}
 #elif defined(IR_TARGET_X64)
@@ -8553,11 +8617,7 @@
 	ir_reg tmp_reg = ctx->regs[def][3];
 	int32_t offset;
 
-	if (ctx->use_lists[def].count == 1) {
-		/* dead load */
-		return;
-	}
-	IR_ASSERT(def_reg != IR_REG_NONE&& tmp_reg != IR_REG_NONE);
+	IR_ASSERT((def_reg != IR_REG_NONE || ctx->use_lists[def].count == 1) && tmp_reg != IR_REG_NONE);
 	if (op2_reg != IR_REG_NONE) {
 		if (IR_REG_SPILLED(op2_reg)) {
 			op2_reg = IR_REG_NUM(op2_reg);
@@ -8580,7 +8640,9 @@
 			|	add Ra(tmp_reg), (align-1)
 			|	and Ra(tmp_reg), ~(align-1)
 		}
-		|	mov Ra(def_reg), Ra(tmp_reg)
+		if (def_reg != IR_REG_NONE) {
+			|	mov Ra(def_reg), Ra(tmp_reg)
+		}
 		|	add Ra(tmp_reg), IR_ALIGNED_SIZE(size, sizeof(void*))
 		|	mov aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, overflow_arg_area))], Ra(tmp_reg)
 	} else if (IR_IS_TYPE_INT(type)) {
@@ -8596,7 +8658,13 @@
 		|	add Ra(tmp_reg), sizeof(void*)
 		|	mov aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, overflow_arg_area))], Ra(tmp_reg)
 		|2:
-		|	mov Ra(def_reg), aword [Ra(tmp_reg)-sizeof(void*)]
+		if (def_reg != IR_REG_NONE) {
+			if (ir_type_size[type] == 8) {
+				|	mov Rq(def_reg), qword [Ra(tmp_reg)-sizeof(void*)]
+			} else {
+				|	mov Rd(def_reg), dword [Ra(tmp_reg)-sizeof(void*)]
+			}
+		}
 	} else {
 		|	mov Rd(tmp_reg), dword [Ra(op2_reg)+(offset+offsetof(ir_va_list, fp_offset))]
 		|	cmp Rd(tmp_reg), sizeof(void*) * IR_REG_INT_ARGS + 16 * IR_REG_FP_ARGS
@@ -8604,16 +8672,20 @@
 		|	add Rd(tmp_reg), 16
 		|	mov dword [Ra(op2_reg)+(offset+offsetof(ir_va_list, fp_offset))], Rd(tmp_reg)
 		|	add Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, reg_save_area))]
-		ir_emit_load_mem_fp(ctx, type, def_reg, IR_MEM_BO(tmp_reg, -16));
+		if (def_reg != IR_REG_NONE) {
+			ir_emit_load_mem_fp(ctx, type, def_reg, IR_MEM_BO(tmp_reg, -16));
+		}
 		|	jmp >2
 		|1:
 		|	mov Ra(tmp_reg), aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, overflow_arg_area))]
-		ir_emit_load_mem_fp(ctx, type, def_reg, IR_MEM_BO(tmp_reg, 0));
+		if (def_reg != IR_REG_NONE) {
+			ir_emit_load_mem_fp(ctx, type, def_reg, IR_MEM_BO(tmp_reg, 0));
+		}
 		|	add Ra(tmp_reg), 8
 		|	mov aword [Ra(op2_reg)+(offset+offsetof(ir_va_list, overflow_arg_area))], Ra(tmp_reg)
 		|2:
 	}
-	if (IR_REG_SPILLED(ctx->regs[def][0])) {
+	if (def_reg != IR_REG_NONE && IR_REG_SPILLED(ctx->regs[def][0])) {
 		ir_emit_store(ctx, type, def, def_reg);
 	}
 |.endif
@@ -9751,6 +9823,12 @@
 							|	jp &addr
 							|	jbe =>target
 							break;
+						case IR_ORDERED:
+							|	jnp =>target
+							break;
+						case IR_UNORDERED:
+							|	jp =>target
+							break;
 					}
 				}
 				|	jmp &addr
@@ -9830,6 +9908,12 @@
 						|	jp &addr
 						|	jbe &target_addr
 						break;
+					case IR_ORDERED:
+						|	jnp &target_addr
+						break;
+					case IR_UNORDERED:
+						|	jp &target_addr
+						break;
 				}
 			}
 			|	jmp &addr
@@ -9909,6 +9993,12 @@
 			case IR_GT:
 				|	ja &addr
 				break;
+			case IR_ORDERED:
+				|	jp &addr
+				break;
+			case IR_UNORDERED:
+				|	jnp &addr
+				break;
 //			case IR_ULT: fprintf(stderr, "\tjb .LL%d\n", true_block); break;
 //			case IR_UGE: fprintf(stderr, "\tjae .LL%d\n", true_block); break;
 //			case IR_ULE: fprintf(stderr, "\tjbe .LL%d\n", true_block); break;
@@ -11019,6 +11109,14 @@
 	dasm_setup(&data.dasm_state, dasm_actions);
 	/* labels for each block + for each constant + rodata label + jmp_table label + for each entry */
 	dasm_growpc(&data.dasm_state, ctx->cfg_blocks_count + 1 + ctx->consts_count + 1 + 1 + 1 + ctx->entries_count);
+	if (data.dasm_state->status != DASM_S_OK) {
+		IR_ASSERT(data.dasm_state->status == DASM_S_NOMEM);
+		dasm_free(&data.dasm_state);
+		ctx->data = NULL;
+		ctx->status = IR_ERROR_TOO_LARGE;
+		return NULL;
+	}
+
 	data.emit_constants = ir_bitset_malloc(ctx->consts_count);
 
 	if ((ctx->flags & IR_GEN_ENDBR) && (ctx->flags & IR_START_BR_TARGET)) {
@@ -11515,12 +11613,20 @@
 		return NULL;
 	}
 
+	if (data.dasm_state->status != DASM_S_OK) {
+		IR_ASSERT(data.dasm_state->status == DASM_S_NOMEM);
+		dasm_free(&data.dasm_state);
+		ctx->data = NULL;
+		ctx->status = IR_ERROR_TOO_LARGE;
+		return NULL;
+	}
+
 	ret = dasm_link(&data.dasm_state, size_ptr);
 	if (ret != DASM_S_OK) {
-		IR_ASSERT(0);
+		IR_ASSERT(ret == DASM_S_NOMEM);
 		dasm_free(&data.dasm_state);
 		ctx->data = NULL;
-		ctx->status = IR_ERROR_LINK;
+		ctx->status = (ret == DASM_S_NOMEM) ? IR_ERROR_TOO_LARGE : IR_ERROR_LINK;
 		return NULL;
 	}
 	size = *size_ptr;
diff '--color=auto' -Naur a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c
--- a/ext/opcache/jit/zend_jit_ir.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/jit/zend_jit_ir.c	2025-11-18 21:43:27.176566035 +0000
@@ -19,6 +19,10 @@
 #include "jit/ir/ir.h"
 #include "jit/ir/ir_builder.h"
 
+#if defined(__APPLE__) && defined(__x86_64__)
+# include <mach-o/dyld.h>
+#endif
+
 #if defined(IR_TARGET_X86)
 # define IR_REG_SP            4 /* IR_REG_RSP */
 # define IR_REG_FP            5 /* IR_REG_RBP */
@@ -3329,6 +3333,24 @@
 }
 #endif
 
+#if defined(__APPLE__) && defined(__x86_64__)
+/* Thunk format used since dydl 1284 (approx. MacOS 15)
+ * https://github.com/apple-oss-distributions/dyld/blob/9307719dd8dc9b385daa412b03cfceb897b2b398/libdyld/ThreadLocalVariables.h#L146 */
+struct TLV_Thunkv2
+{
+       void*        func;
+       uint32_t     key;
+       uint32_t     offset;
+};
+
+/* Thunk format used in earlier versions */
+struct TLV_Thunkv1
+{
+       void*       func;
+       size_t      key;
+       size_t      offset;
+};
+#endif
 
 static void zend_jit_setup(bool reattached)
 {
@@ -3436,12 +3458,25 @@
 # elif defined(__APPLE__) && defined(__x86_64__)
 	tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset();
 	if (tsrm_ls_cache_tcb_offset == 0) {
-		size_t *ti;
+		struct TLV_Thunkv2 *thunk;
 		__asm__(
 			"leaq __tsrm_ls_cache(%%rip),%0"
-			: "=r" (ti));
-		tsrm_tls_offset = ti[2];
-		tsrm_tls_index = ti[1] * 8;
+			: "=r" (thunk));
+
+		/* Detect dyld 1284: With dyld 1284, thunk->func will be _tlv_get_addr.
+		 * Unfortunately this symbol is private, but we can find it
+		 * as _tlv_bootstrap+8: https://github.com/apple-oss-distributions/dyld/blob/9307719dd8dc9b385daa412b03cfceb897b2b398/libdyld/threadLocalHelpers.s#L54
+		 * In earlier versions, thunk->func will be tlv_get_addr, which is not
+		 * _tlv_bootstrap+8.
+		 */
+		if (thunk->func == (void*)((char*)_tlv_bootstrap + 8)) {
+			tsrm_tls_offset = thunk->offset;
+			tsrm_tls_index = (size_t)thunk->key * 8;
+		} else {
+			struct TLV_Thunkv1 *thunkv1 = (struct TLV_Thunkv1*) thunk;
+			tsrm_tls_offset = thunkv1->offset;
+			tsrm_tls_index = thunkv1->key * 8;
+		}
 	}
 # elif defined(__GNUC__) && defined(__x86_64__)
 	tsrm_ls_cache_tcb_offset = tsrm_get_ls_cache_tcb_offset();
diff '--color=auto' -Naur a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c
--- a/ext/opcache/zend_file_cache.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/opcache/zend_file_cache.c	2025-11-18 21:43:27.178143423 +0000
@@ -535,13 +535,32 @@
 			}
 			if (opline->op2_type == IS_CONST) {
 				SERIALIZE_PTR(opline->op2.zv);
+
+				/* See GH-17733. Reset Z_EXTRA_P(op2) of ZEND_INIT_FCALL, which
+				 * is an offset into the global function table, to avoid calling
+				 * incorrect functions when environment changes. This, and the
+				 * equivalent code below, can be removed once proper system ID
+				 * validation is implemented. */
+				if (opline->opcode == ZEND_INIT_FCALL) {
+					zval *op2 = opline->op2.zv;
+					UNSERIALIZE_PTR(op2);
+					Z_EXTRA_P(op2) = 0;
+					ZEND_VM_SET_OPCODE_HANDLER(opline);
+				}
 			}
 #else
 			if (opline->op1_type == IS_CONST) {
 				opline->op1.constant = RT_CONSTANT(opline, opline->op1) - literals;
 			}
 			if (opline->op2_type == IS_CONST) {
-				opline->op2.constant = RT_CONSTANT(opline, opline->op2) - literals;
+				zval *op2 = RT_CONSTANT(opline, opline->op2);
+				opline->op2.constant = op2 - literals;
+
+				/* See GH-17733 and comment above. */
+				if (opline->opcode == ZEND_INIT_FCALL) {
+					Z_EXTRA_P(op2) = 0;
+					ZEND_VM_SET_OPCODE_HANDLER(opline);
+				}
 			}
 #endif
 #if ZEND_USE_ABS_JMP_ADDR
diff '--color=auto' -Naur a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
--- a/ext/openssl/xp_ssl.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/openssl/xp_ssl.c	2025-11-18 21:43:27.178877739 +0000
@@ -2338,7 +2338,7 @@
 static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_netstream_data_t *sock,
 		php_stream_xport_param *xparam STREAMS_DC)  /* {{{ */
 {
-	int clisock;
+	php_socket_t clisock;
 	bool nodelay = 0;
 	zval *tmpzval = NULL;
 
@@ -2359,7 +2359,7 @@
 		&xparam->outputs.error_code,
 		nodelay);
 
-	if (clisock >= 0) {
+	if (clisock != SOCK_ERR) {
 		php_openssl_netstream_data_t *clisockdata = (php_openssl_netstream_data_t*) emalloc(sizeof(*clisockdata));
 
 		/* copy underlying tcp fields */
diff '--color=auto' -Naur a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c
--- a/ext/pdo_mysql/mysql_statement.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/pdo_mysql/mysql_statement.c	2025-11-18 21:43:27.179797646 +0000
@@ -715,7 +715,7 @@
 
 static char *type_to_name_native(int type) /* {{{ */
 {
-#define PDO_MYSQL_NATIVE_TYPE_NAME(x)	case FIELD_TYPE_##x: return #x;
+#define PDO_MYSQL_NATIVE_TYPE_NAME(x)	case MYSQL_TYPE_##x: return #x;
 
 	switch (type) {
 		PDO_MYSQL_NATIVE_TYPE_NAME(STRING)
@@ -749,6 +749,13 @@
 #ifdef FIELD_TYPE_NEWDATE
 		PDO_MYSQL_NATIVE_TYPE_NAME(NEWDATE)
 #endif
+		/* The following 2 don't have BC FIELD_TYPE_* aliases. */
+#if (MYSQL_VERSION_ID >= 90000 && !defined(MARIADB_BASE_VERSION)) || defined(PDO_USE_MYSQLND)
+		PDO_MYSQL_NATIVE_TYPE_NAME(VECTOR)
+#endif
+#if MYSQL_VERSION_ID >= 50708 || defined(PDO_USE_MYSQLND)
+		PDO_MYSQL_NATIVE_TYPE_NAME(JSON)
+#endif
 		PDO_MYSQL_NATIVE_TYPE_NAME(TIME)
 		PDO_MYSQL_NATIVE_TYPE_NAME(DATETIME)
 		PDO_MYSQL_NATIVE_TYPE_NAME(TINY_BLOB)
diff '--color=auto' -Naur a/ext/pdo_mysql/tests/gh20122.phpt b/ext/pdo_mysql/tests/gh20122.phpt
--- a/ext/pdo_mysql/tests/gh20122.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/pdo_mysql/tests/gh20122.phpt	2025-11-18 21:43:27.180227027 +0000
@@ -0,0 +1,32 @@
+--TEST--
+GH-20122 (getColumnMeta() for JSON-column in MySQL)
+--EXTENSIONS--
+pdo
+pdo_mysql
+--SKIPIF--
+<?php
+require_once __DIR__ . '/inc/mysql_pdo_test.inc';
+MySQLPDOTest::skip();
+?>
+--FILE--
+<?php
+require_once __DIR__ . '/inc/mysql_pdo_test.inc';
+$db = MySQLPDOTest::factory();
+
+$db->exec('CREATE TABLE test_gh20122 (bar JSON)');
+$db->exec('INSERT INTO test_gh20122 VALUES("[]")');
+
+$stmt = $db->query('SELECT * from test_gh20122');
+$meta = $stmt->getColumnMeta(0);
+
+// Note: JSON is an alias for LONGTEXT on MariaDB!
+echo $meta['native_type'], "\n";
+?>
+--CLEAN--
+<?php
+require_once __DIR__ . '/inc/mysql_pdo_test.inc';
+$pdo = MySQLPDOTest::factory();
+$pdo->query('DROP TABLE IF EXISTS test_gh20122');
+?>
+--EXPECTF--
+%r(JSON|LONGTEXT)%r
diff '--color=auto' -Naur a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
--- a/ext/pgsql/pgsql.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/pgsql/pgsql.c	2025-11-18 21:43:27.180566087 +0000
@@ -1210,15 +1210,13 @@
 
 static void _php_pgsql_free_params(char **params, int num_params)
 {
-	if (num_params > 0) {
-		int i;
-		for (i = 0; i < num_params; i++) {
-			if (params[i]) {
-				efree(params[i]);
-			}
+	int i;
+	for (i = 0; i < num_params; i++) {
+		if (params[i]) {
+			efree(params[i]);
 		}
-		efree(params);
 	}
+	efree(params);
 }
 
 /* Execute a query */
@@ -2066,7 +2064,10 @@
 		zval dataset;
 
 		ZVAL_COPY_VALUE(&dataset, return_value);
-		object_init_ex(return_value, ce);
+		zend_result obj_initialized = object_init_ex(return_value, ce);
+		if (UNEXPECTED(obj_initialized == FAILURE)) {
+			RETURN_THROWS();
+		}
 		if (!ce->default_properties_count && !ce->__set) {
 			Z_OBJ_P(return_value)->properties = Z_ARR(dataset);
 		} else {
diff '--color=auto' -Naur a/ext/pgsql/tests/inc/config.inc b/ext/pgsql/tests/inc/config.inc
--- a/ext/pgsql/tests/inc/config.inc	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/pgsql/tests/inc/config.inc	2025-11-18 21:43:27.182196184 +0000
@@ -6,4 +6,3 @@
 
 // "test" database must exist. i.e. "createdb test" before testing
 $conn_str = getenv('PGSQL_TEST_CONNSTR') ?: "host=localhost dbname=test port=5432 user=postgres password=postgres";    // connection string
-?>
diff '--color=auto' -Naur a/ext/pgsql/tests/inc/lcmess.inc b/ext/pgsql/tests/inc/lcmess.inc
--- a/ext/pgsql/tests/inc/lcmess.inc	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/pgsql/tests/inc/lcmess.inc	2025-11-18 21:43:27.182363861 +0000
@@ -17,5 +17,3 @@
 
     return true;
 }
-
-?>
diff '--color=auto' -Naur a/ext/pgsql/tests/inc/skipif.inc b/ext/pgsql/tests/inc/skipif.inc
--- a/ext/pgsql/tests/inc/skipif.inc	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/pgsql/tests/inc/skipif.inc	2025-11-18 21:43:27.182467637 +0000
@@ -1,4 +1,3 @@
-
 <?php
 // This script prints "skip" unless:
 // * the pgsql extension is built-in or loadable, AND
@@ -47,5 +46,3 @@
         die("skip libpq or backend >= 9.0\n");
     }
 }
-
-?>
diff '--color=auto' -Naur a/ext/pgsql/tests/pg_fetch_object_with_abstract_class.phpt b/ext/pgsql/tests/pg_fetch_object_with_abstract_class.phpt
--- a/ext/pgsql/tests/pg_fetch_object_with_abstract_class.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/pgsql/tests/pg_fetch_object_with_abstract_class.phpt	2025-11-18 21:43:27.182600458 +0000
@@ -0,0 +1,59 @@
+--TEST--
+pg_fetch_object() with abstract class name
+--EXTENSIONS--
+pgsql
+--SKIPIF--
+<?php
+include("inc/skipif.inc");
+?>
+--FILE--
+<?php
+
+interface I {}
+
+abstract class C {}
+
+enum E {
+	case A;
+}
+
+include "inc/config.inc";
+$table_name = "pg_fetch_object_abstract_class";
+$db = pg_connect($conn_str);
+pg_query($db, "CREATE TABLE {$table_name} (a integer, b text)");
+pg_query($db, "INSERT INTO {$table_name} VALUES(0, 'ABC')");
+
+$sql = "SELECT * FROM $table_name WHERE a = 0";
+
+try {
+	$result = pg_query($db, $sql);
+	var_dump(pg_fetch_object($result, NULL, 'I'));
+} catch(Throwable $e) {
+	echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+try {
+	$result = pg_query($db, $sql);
+	var_dump(pg_fetch_object($result, NULL, 'C'));
+} catch(Throwable $e) {
+	echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+try {
+	$result = pg_query($db, $sql);
+	var_dump(pg_fetch_object($result, NULL, 'E'));
+} catch(Throwable $e) {
+	echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--CLEAN--
+<?php
+include('inc/config.inc');
+$db = @pg_connect($conn_str);
+@pg_query($db, "DROP TABLE IF EXISTS pg_fetch_object_abstract_class cascade");
+?>
+--EXPECT--
+Error: Cannot instantiate interface I
+Error: Cannot instantiate abstract class C
+Error: Cannot instantiate enum E
diff '--color=auto' -Naur a/ext/phar/phar.c b/ext/phar/phar.c
--- a/ext/phar/phar.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/phar/phar.c	2025-11-18 21:43:27.182745251 +0000
@@ -1592,7 +1592,7 @@
 }
 /* }}}*/
 
-static inline char *phar_strnstr(const char *buf, int buf_len, const char *search, int search_len) /* {{{ */
+static inline char *phar_strnstr(const char *buf, size_t buf_len, const char *search, size_t search_len) /* {{{ */
 {
 	const char *c;
 	ptrdiff_t so_far = 0;
@@ -1674,6 +1674,12 @@
 				if (!PHAR_G(has_zlib)) {
 					MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\" to temporary file, enable zlib extension in php.ini")
 				}
+
+				/* entire file is gzip-compressed, uncompress to temporary file */
+				if (!(temp = php_stream_fopen_tmpfile())) {
+					MAPPHAR_ALLOC_FAIL("unable to create temporary file for decompression of gzipped phar archive \"%s\"")
+				}
+
 				array_init(&filterparams);
 /* this is defined in zlib's zconf.h */
 #ifndef MAX_WBITS
@@ -1681,11 +1687,6 @@
 #endif
 				add_assoc_long_ex(&filterparams, "window", sizeof("window") - 1, MAX_WBITS + 32);
 
-				/* entire file is gzip-compressed, uncompress to temporary file */
-				if (!(temp = php_stream_fopen_tmpfile())) {
-					MAPPHAR_ALLOC_FAIL("unable to create temporary file for decompression of gzipped phar archive \"%s\"")
-				}
-
 				php_stream_rewind(fp);
 				filter = php_stream_filter_create("zlib.inflate", &filterparams, php_stream_is_persistent(fp));
 
diff '--color=auto' -Naur a/ext/phar/phar_object.c b/ext/phar/phar_object.c
--- a/ext/phar/phar_object.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/phar/phar_object.c	2025-11-18 21:43:27.184566139 +0000
@@ -697,12 +697,15 @@
 		rewrite_fci.retval = &retval;
 
 		if (FAILURE == zend_call_function(&rewrite_fci, &rewrite_fcc)) {
+			zval_ptr_dtor_str(&params);
 			if (!EG(exception)) {
 				zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: failed to call rewrite callback");
 			}
 			goto cleanup_fail;
 		}
 
+		zval_ptr_dtor_str(&params);
+
 		if (Z_TYPE_P(rewrite_fci.retval) == IS_UNDEF || Z_TYPE(retval) == IS_UNDEF) {
 			zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: rewrite callback must return a string or false");
 			goto cleanup_fail;
@@ -728,7 +731,6 @@
 				zend_throw_exception_ex(phar_ce_PharException, 0, "phar error: rewrite callback must return a string or false");
 
 cleanup_fail:
-				zval_ptr_dtor(&params);
 				if (free_pathinfo) {
 					efree(path_info);
 				}
@@ -1790,6 +1792,10 @@
 	pass.ret = return_value;
 	pass.fp = php_stream_fopen_tmpfile();
 	if (pass.fp == NULL) {
+		zval_ptr_dtor(&iteriter);
+		if (apply_reg) {
+			zval_ptr_dtor(&regexiter);
+		}
 		zend_throw_exception_ex(phar_ce_PharException, 0, "phar \"%s\" unable to create temporary file", phar_obj->archive->fname);
 		RETURN_THROWS();
 	}
@@ -2776,6 +2782,7 @@
 	phar_flush(phar_obj->archive, &error);
 
 	if (error) {
+		pefree(phar_obj->archive->alias, phar_obj->archive->is_persistent);
 		phar_obj->archive->alias = oldalias;
 		phar_obj->archive->alias_len = oldalias_len;
 		phar_obj->archive->is_temporary_alias = old_temp;
@@ -4513,6 +4520,9 @@
 	entry_obj->entry = entry_info;
 	if (!entry_info->is_persistent && !entry_info->is_temp_dir) {
 		++entry_info->fp_refcount;
+		/* The phar data must exist to keep the alias locked. */
+		ZEND_ASSERT(!phar_data->is_persistent);
+		++phar_data->refcount;
 	}
 
 	ZVAL_STRINGL(&arg1, fname, fname_len);
@@ -4543,23 +4553,26 @@
 		RETURN_THROWS();
 	}
 
-	if (!entry_obj->entry) {
+	phar_entry_info *entry = entry_obj->entry;
+	if (!entry) {
 		return;
 	}
 
-	if (entry_obj->entry->is_temp_dir) {
-		if (entry_obj->entry->filename) {
-			efree(entry_obj->entry->filename);
-			entry_obj->entry->filename = NULL;
+	if (entry->is_temp_dir) {
+		if (entry->filename) {
+			efree(entry->filename);
+			entry->filename = NULL;
 		}
 
-		efree(entry_obj->entry);
-	} else if (!entry_obj->entry->is_persistent) {
-		--entry_obj->entry->fp_refcount;
-		/* It is necessarily still in the manifest, which will ultimately free this. */
+		efree(entry);
+		entry_obj->entry = NULL;
+	} else if (!entry->is_persistent) {
+		--entry->fp_refcount;
+		/* The entry itself still lives in the manifest,
+		 * which will either be freed here if the file info was the last reference; or freed later. */
+		entry_obj->entry = NULL;
+		phar_archive_delref(entry->phar);
 	}
-
-	entry_obj->entry = NULL;
 }
 /* }}} */
 
diff '--color=auto' -Naur a/ext/phar/stream.c b/ext/phar/stream.c
--- a/ext/phar/stream.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/phar/stream.c	2025-11-18 21:43:27.185806230 +0000
@@ -670,7 +670,7 @@
 {
 	php_url *resource;
 	char *internal_file, *error;
-	int internal_file_len;
+	size_t internal_file_len;
 	phar_entry_data *idata;
 	phar_archive_data *pphar;
 
diff '--color=auto' -Naur a/ext/phar/tests/gh20302.phpt b/ext/phar/tests/gh20302.phpt
--- a/ext/phar/tests/gh20302.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/phar/tests/gh20302.phpt	2025-11-18 21:43:27.186390082 +0000
@@ -0,0 +1,36 @@
+--TEST--
+GH-20302 (Freeing a phar alias may invalidate PharFileInfo objects)
+--EXTENSIONS--
+phar
+--INI--
+phar.require_hash=0
+--FILE--
+<?php
+$fname = __DIR__.'/gh20302.phar';
+$pname = 'phar://' . $fname;
+$file = "<?php
+__HALT_COMPILER(); ?>";
+$files = array();
+$files['here'] = 'a';
+include __DIR__.'/files/phar_test.inc';
+$b = new PharFileInfo($pname . '/here');
+
+// Create new phar with same alias and open it
+@mkdir(__DIR__.'/gh20302');
+$fname = __DIR__.'/gh20302/gh20302.phar';
+$pname = 'phar://' . $fname;
+include __DIR__.'/files/phar_test.inc';
+try {
+    new Phar($fname);
+} catch (UnexpectedValueException $e) {
+    echo $e->getMessage(), "\n";
+}
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__.'/gh20302/gh20302.phar');
+@unlink(__DIR__.'/gh20302.phar');
+@rmdir(__DIR__.'/gh20302');
+?>
+--EXPECTF--
+Cannot open archive "%sgh20302.phar", alias is already in use by existing archive
diff '--color=auto' -Naur a/ext/phar/tests/openssl_sign_invalid_polyfill_return_value.phpt b/ext/phar/tests/openssl_sign_invalid_polyfill_return_value.phpt
--- a/ext/phar/tests/openssl_sign_invalid_polyfill_return_value.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/phar/tests/openssl_sign_invalid_polyfill_return_value.phpt	2025-11-18 21:43:27.186719755 +0000
@@ -0,0 +1,34 @@
+--TEST--
+openssl_sign() polyfill with wrong return value
+--EXTENSIONS--
+phar
+--SKIPIF--
+<?php
+if (getenv('SKIP_SLOW_TESTS')) die('skip');
+if (function_exists('openssl_sign')) die('skip requires openssl disabled for mocking purposes');
+?>
+--INI--
+phar.require_hash=0
+--FILE--
+<?php
+$fname = __DIR__ . '/' . basename(__FILE__, '.php') . '.tar';
+
+function openssl_sign() {
+    return str_repeat('foobar', random_int(1, 1));
+}
+
+$phar = new PharData($fname);
+$phar->setSignatureAlgorithm(Phar::OPENSSL, "randomcrap");
+try {
+    $phar->addEmptyDir('blah');
+} catch (PharException $e) {
+    echo $e->getMessage();
+}
+
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.tar');
+?>
+--EXPECTF--
+phar error: unable to write signature to tar-based phar: unable to write phar "%s" with requested openssl signature
diff '--color=auto' -Naur a/ext/phar/tests/tar/bug70417.phpt b/ext/phar/tests/tar/bug70417.phpt
--- a/ext/phar/tests/tar/bug70417.phpt	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/phar/tests/tar/bug70417.phpt	2025-11-18 21:43:27.186798082 +0000
@@ -3,32 +3,17 @@
 --EXTENSIONS--
 phar
 zlib
---SKIPIF--
-<?php
-
-exec('lsof -p ' . getmypid(), $out, $status);
-if ($status !== 0) {
-    die("skip lsof(8) not available");
-}
-if (!str_starts_with($out[0], 'COMMAND')) {
-    die("skip Might be a different lsof");
-}
-?>
 --FILE--
 <?php
-function countOpenFiles() {
-    exec('lsof -p ' . escapeshellarg(getmypid()) . ' 2> /dev/null', $out);  // Note: valgrind can produce false positives for /usr/bin/lsof
-    return count($out);
-}
 $filename = __DIR__ . '/bug70417.tar';
 @unlink("$filename.gz");
-$openFiles1 = countOpenFiles();
+$resBefore = count(get_resources());
 $arch = new PharData($filename);
 $arch->addFromString('foo', 'bar');
 $arch->compress(Phar::GZ);
 unset($arch);
-$openFiles2 = countOpenFiles();
-var_dump($openFiles1 === $openFiles2);
+$resAfter = count(get_resources());
+var_dump($resBefore === $resAfter);
 ?>
 --CLEAN--
 <?php
diff '--color=auto' -Naur a/ext/phar/util.c b/ext/phar/util.c
--- a/ext/phar/util.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/phar/util.c	2025-11-18 21:43:27.187069705 +0000
@@ -1520,7 +1520,6 @@
 	zval_ptr_dtor_str(&zp[2]);
 
 	switch (Z_TYPE(retval)) {
-		default:
 		case IS_LONG:
 			zval_ptr_dtor(&zp[1]);
 			if (1 == Z_LVAL(retval)) {
@@ -1532,6 +1531,9 @@
 			*signature_len = Z_STRLEN(zp[1]);
 			zval_ptr_dtor(&zp[1]);
 			return SUCCESS;
+		default:
+			zval_ptr_dtor(&retval);
+			ZEND_FALLTHROUGH;
 		case IS_FALSE:
 			zval_ptr_dtor(&zp[1]);
 			return FAILURE;
diff '--color=auto' -Naur a/ext/phar/zip.c b/ext/phar/zip.c
--- a/ext/phar/zip.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/phar/zip.c	2025-11-18 21:43:27.187806206 +0000
@@ -345,29 +345,8 @@
 	entry.is_zip = 1;
 	entry.fp_type = PHAR_FP;
 	entry.is_persistent = mydata->is_persistent;
-#define PHAR_ZIP_FAIL_FREE(errmsg, save) \
-			zend_hash_destroy(&mydata->manifest); \
-			HT_INVALIDATE(&mydata->manifest); \
-			zend_hash_destroy(&mydata->mounted_dirs); \
-			HT_INVALIDATE(&mydata->mounted_dirs); \
-			zend_hash_destroy(&mydata->virtual_dirs); \
-			HT_INVALIDATE(&mydata->virtual_dirs); \
-			php_stream_close(fp); \
-			phar_metadata_tracker_free(&mydata->metadata_tracker, mydata->is_persistent); \
-			if (mydata->signature) { \
-				efree(mydata->signature); \
-			} \
-			if (error) { \
-				spprintf(error, 4096, "phar error: %s in zip-based phar \"%s\"", errmsg, mydata->fname); \
-			} \
-			pefree(mydata->fname, mydata->is_persistent); \
-			if (mydata->alias) { \
-				pefree(mydata->alias, mydata->is_persistent); \
-			} \
-			pefree(mydata, mydata->is_persistent); \
-			efree(save); \
-			return FAILURE;
 #define PHAR_ZIP_FAIL(errmsg) \
+			efree(actual_alias); \
 			zend_hash_destroy(&mydata->manifest); \
 			HT_INVALIDATE(&mydata->manifest); \
 			zend_hash_destroy(&mydata->mounted_dirs); \
@@ -521,14 +500,13 @@
 			mydata->sig_flags = PHAR_GET_32(sig);
 			if (FAILURE == phar_verify_signature(sigfile, php_stream_tell(sigfile), mydata->sig_flags, sig + 8, entry.uncompressed_filesize - 8, fname, &mydata->signature, &sig_len, error)) {
 				efree(sig);
+				php_stream_close(sigfile);
 				if (error) {
-					char *save;
-					php_stream_close(sigfile);
-					spprintf(&save, 4096, "signature cannot be verified: %s", *error);
+					char errmsg[128];
+					snprintf(errmsg, sizeof(errmsg), "signature cannot be verified: %s", *error);
 					efree(*error);
-					PHAR_ZIP_FAIL_FREE(save, save);
+					PHAR_ZIP_FAIL(errmsg);
 				} else {
-					php_stream_close(sigfile);
 					PHAR_ZIP_FAIL("signature cannot be verified");
 				}
 			}
@@ -673,7 +651,7 @@
 					}
 				}
 
-				if (!entry.uncompressed_filesize || !actual_alias) {
+				if (!entry.uncompressed_filesize) {
 					php_stream_filter_remove(filter, 1);
 					pefree(entry.filename, entry.is_persistent);
 					PHAR_ZIP_FAIL("unable to read in alias, truncated");
@@ -706,7 +684,7 @@
 					}
 				}
 
-				if (!entry.uncompressed_filesize || !actual_alias) {
+				if (!entry.uncompressed_filesize) {
 					php_stream_filter_remove(filter, 1);
 					pefree(entry.filename, entry.is_persistent);
 					PHAR_ZIP_FAIL("unable to read in alias, truncated");
@@ -729,7 +707,7 @@
 					}
 				}
 
-				if (!entry.uncompressed_filesize || !actual_alias) {
+				if (!entry.uncompressed_filesize) {
 					pefree(entry.filename, entry.is_persistent);
 					PHAR_ZIP_FAIL("unable to read in alias, truncated");
 				}
@@ -1298,6 +1276,7 @@
 			return;
 		}
 		if (phar->alias_len != php_stream_write(entry.fp, phar->alias, phar->alias_len)) {
+			php_stream_close(entry.fp);
 			if (error) {
 				spprintf(error, 0, "unable to set alias in zip-based phar \"%s\"", phar->fname);
 			}
@@ -1422,6 +1401,7 @@
 	pass.centralfp = php_stream_fopen_tmpfile();
 
 	if (!pass.centralfp) {
+		php_stream_close(pass.filefp);
 		goto fperror;
 	}
 
diff '--color=auto' -Naur a/ext/random/engine_mt19937.c b/ext/random/engine_mt19937.c
--- a/ext/random/engine_mt19937.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/random/engine_mt19937.c	2025-11-18 21:43:27.188509353 +0000
@@ -330,11 +330,11 @@
 
 	/* state */
 	array_init(&t);
+	zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &t);
 	if (!engine->engine.algo->serialize(engine->engine.state, Z_ARRVAL(t))) {
 		zend_throw_exception(NULL, "Engine serialize failed", 0);
 		RETURN_THROWS();
 	}
-	zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &t);
 }
 /* }}} */
 
diff '--color=auto' -Naur a/ext/random/randomizer.c b/ext/random/randomizer.c
--- a/ext/random/randomizer.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/random/randomizer.c	2025-11-18 21:43:27.188832533 +0000
@@ -516,8 +516,7 @@
 	ZEND_PARSE_PARAMETERS_NONE();
 
 	array_init(return_value);
-	ZVAL_ARR(&t, zend_std_get_properties(&randomizer->std));
-	Z_TRY_ADDREF(t);
+	ZVAL_ARR(&t, zend_array_dup(zend_std_get_properties(&randomizer->std)));
 	zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &t);
 }
 /* }}} */
diff '--color=auto' -Naur a/ext/random/tests/03_randomizer/methods/__serialize_indirects.phpt b/ext/random/tests/03_randomizer/methods/__serialize_indirects.phpt
--- a/ext/random/tests/03_randomizer/methods/__serialize_indirects.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/random/tests/03_randomizer/methods/__serialize_indirects.phpt	2025-11-18 21:43:27.189151626 +0000
@@ -0,0 +1,18 @@
+--TEST--
+Random: Engine: __serialize() must not expose INDIRECTs
+--FILE--
+<?php
+
+$randomizer = new Random\Randomizer(null);
+var_dump($randomizer->__serialize());
+
+?>
+--EXPECT--
+array(1) {
+  [0]=>
+  array(1) {
+    ["engine"]=>
+    object(Random\Engine\Secure)#2 (0) {
+    }
+  }
+}
diff '--color=auto' -Naur a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
--- a/ext/reflection/php_reflection.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/reflection/php_reflection.c	2025-11-18 21:43:27.190566216 +0000
@@ -5696,7 +5696,8 @@
 		RETURN_FALSE;
 	}
 
-	RETURN_BOOL(ce->get_iterator || instanceof_function(ce, zend_ce_traversable));
+	RETURN_BOOL((ce->get_iterator && ce->get_iterator != zend_hooked_object_get_iterator)
+				|| instanceof_function(ce, zend_ce_traversable));
 }
 /* }}} */
 
diff '--color=auto' -Naur a/ext/reflection/tests/ReflectionClass_isIterable_gh20217.phpt b/ext/reflection/tests/ReflectionClass_isIterable_gh20217.phpt
--- a/ext/reflection/tests/ReflectionClass_isIterable_gh20217.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/reflection/tests/ReflectionClass_isIterable_gh20217.phpt	2025-11-18 21:43:27.191313647 +0000
@@ -0,0 +1,38 @@
+--TEST--
+GH-20217 (ReflectionClass::isIterable() should return false for classes with property hooks)
+--FILE--
+<?php
+
+class ClassWithPropertyHooks
+{
+    public string $name {
+        get => 'virtual';
+    }
+}
+
+class IterableClassWithPropertyHooks implements IteratorAggregate
+{
+    public string $name {
+        get => 'virtual';
+    }
+
+    public function getIterator(): Traversable
+    {
+        return new ArrayIterator([]);
+    }
+}
+
+$classes = [
+    'ClassWithPropertyHooks' => false,
+    'IterableClassWithPropertyHooks' => true,
+];
+
+foreach ($classes as $className => $expected) {
+    $status = (new ReflectionClass($className)->isIterable() === $expected) ? 'PASS' : 'FAIL';
+    echo "$className: $status\n";
+}
+
+?>
+--EXPECT--
+ClassWithPropertyHooks: PASS
+IterableClassWithPropertyHooks: PASS
diff '--color=auto' -Naur a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
--- a/ext/simplexml/simplexml.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/simplexml/simplexml.c	2025-11-18 21:43:27.191566229 +0000
@@ -1202,12 +1202,12 @@
 }
 /* }}} */
 
-static HashTable * sxe_get_debug_info(zend_object *object, int *is_temp) /* {{{ */
+/* This custom handler exists because the var_dump adds a pseudo "@attributes" key. */
+PHP_METHOD(SimpleXMLElement, __debugInfo)
 {
-	*is_temp = 1;
-	return sxe_get_prop_hash(object, 1);
+	ZEND_PARSE_PARAMETERS_NONE();
+	RETURN_ARR(sxe_get_prop_hash(Z_OBJ_P(ZEND_THIS), 1));
 }
-/* }}} */
 
 static int sxe_objects_compare(zval *object1, zval *object2) /* {{{ */
 {
@@ -2682,7 +2682,6 @@
 	sxe_object_handlers.compare = sxe_objects_compare;
 	sxe_object_handlers.cast_object = sxe_object_cast;
 	sxe_object_handlers.count_elements = sxe_count_elements;
-	sxe_object_handlers.get_debug_info = sxe_get_debug_info;
 	sxe_object_handlers.get_closure = NULL;
 	sxe_object_handlers.get_gc = sxe_get_gc;
 
diff '--color=auto' -Naur a/ext/simplexml/simplexml.stub.php b/ext/simplexml/simplexml.stub.php
--- a/ext/simplexml/simplexml.stub.php	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/simplexml/simplexml.stub.php	2025-11-18 21:43:27.192320458 +0000
@@ -51,6 +51,8 @@
 
     public function __toString(): string {}
 
+    public function __debugInfo(): ?array {}
+
     /** @tentative-return-type */
     public function count(): int {}
 
diff '--color=auto' -Naur a/ext/simplexml/simplexml_arginfo.h b/ext/simplexml/simplexml_arginfo.h
--- a/ext/simplexml/simplexml_arginfo.h	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/simplexml/simplexml_arginfo.h	2025-11-18 21:43:27.192466664 +0000
@@ -1,5 +1,5 @@
 /* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 36eac2dee86bcc386c24e2cc14caa7bd3d709e82 */
+ * Stub hash: cee51320f0f09f14962fb72125ef8ff6073a642a */
 
 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,6 +79,9 @@
 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_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement_count, 0, 0, IS_LONG, 0)
 ZEND_END_ARG_INFO()
 
@@ -115,6 +118,7 @@
 ZEND_METHOD(SimpleXMLElement, addAttribute);
 ZEND_METHOD(SimpleXMLElement, getName);
 ZEND_METHOD(SimpleXMLElement, __toString);
+ZEND_METHOD(SimpleXMLElement, __debugInfo);
 ZEND_METHOD(SimpleXMLElement, count);
 ZEND_METHOD(SimpleXMLElement, rewind);
 ZEND_METHOD(SimpleXMLElement, valid);
@@ -145,6 +149,7 @@
 	ZEND_ME(SimpleXMLElement, addAttribute, arginfo_class_SimpleXMLElement_addAttribute, ZEND_ACC_PUBLIC)
 	ZEND_ME(SimpleXMLElement, getName, arginfo_class_SimpleXMLElement_getName, ZEND_ACC_PUBLIC)
 	ZEND_ME(SimpleXMLElement, __toString, arginfo_class_SimpleXMLElement___toString, ZEND_ACC_PUBLIC)
+	ZEND_ME(SimpleXMLElement, __debugInfo, arginfo_class_SimpleXMLElement___debugInfo, ZEND_ACC_PUBLIC)
 	ZEND_ME(SimpleXMLElement, count, arginfo_class_SimpleXMLElement_count, ZEND_ACC_PUBLIC)
 	ZEND_ME(SimpleXMLElement, rewind, arginfo_class_SimpleXMLElement_rewind, ZEND_ACC_PUBLIC)
 	ZEND_ME(SimpleXMLElement, valid, arginfo_class_SimpleXMLElement_valid, ZEND_ACC_PUBLIC)
diff '--color=auto' -Naur a/ext/simplexml/tests/gh16317.phpt b/ext/simplexml/tests/gh16317.phpt
--- a/ext/simplexml/tests/gh16317.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/simplexml/tests/gh16317.phpt	2025-11-18 21:43:27.192750350 +0000
@@ -0,0 +1,22 @@
+--TEST--
+GH-16317 (SimpleXML does not allow __debugInfo() overrides to work)
+--FILE--
+<?php
+
+class MySXE extends SimpleXMLElement {
+    public function __debugInfo(): array {
+        echo "invoked\n";
+        return ['x' => 1];
+    }
+}
+
+$sxe = simplexml_load_string('<root><a/></root>', MySXE::class);
+var_dump($sxe);
+
+?>
+--EXPECT--
+invoked
+object(MySXE)#1 (1) {
+  ["x"]=>
+  int(1)
+}
diff '--color=auto' -Naur a/ext/standard/tests/serialize/shm_corruption_coercion_unserialize_options.phpt b/ext/standard/tests/serialize/shm_corruption_coercion_unserialize_options.phpt
--- a/ext/standard/tests/serialize/shm_corruption_coercion_unserialize_options.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/standard/tests/serialize/shm_corruption_coercion_unserialize_options.phpt	2025-11-18 21:43:27.192895394 +0000
@@ -0,0 +1,14 @@
+--TEST--
+Shm corruption with coercion in options of unserialize()
+--FILE--
+<?php
+class MyStringable {
+    public function __toString(): string {
+        return "0";
+    }
+}
+
+unserialize("{}", ["allowed_classes" => [new MyStringable]]);
+?>
+--EXPECTF--
+Warning: unserialize(): Error at offset 0 of 2 bytes in %s on line %d
diff '--color=auto' -Naur a/ext/standard/tests/streams/bug60602.phpt b/ext/standard/tests/streams/bug60602.phpt
--- a/ext/standard/tests/streams/bug60602.phpt	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/standard/tests/streams/bug60602.phpt	2025-11-18 21:43:27.193067128 +0000
@@ -9,7 +9,7 @@
     2 => array('pipe', 'w'), // strerr
 );
 
-$environment = array('test' => array(1, 2, 3));
+$environment = array('test' => array(1, 2, 3), 'PATH' => getenv('PATH'));
 
 $cmd = (substr(PHP_OS, 0, 3) == 'WIN') ? 'dir' : 'ls';
 $p = proc_open($cmd, $descs, $pipes, '.', $environment);
diff '--color=auto' -Naur a/ext/standard/var.c b/ext/standard/var.c
--- a/ext/standard/var.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/standard/var.c	2025-11-18 21:43:27.193277315 +0000
@@ -1414,19 +1414,20 @@
 						function_name, zend_zval_value_name(entry));
 					goto cleanup;
 				}
-				zend_string *name = zval_try_get_string(entry);
+				zend_string *tmp_str;
+				zend_string *name = zval_try_get_tmp_string(entry, &tmp_str);
 				if (UNEXPECTED(name == NULL)) {
 					goto cleanup;
 				}
 				if (UNEXPECTED(!zend_is_valid_class_name(name))) {
 					zend_value_error("%s(): Option \"allowed_classes\" must be an array of class names, \"%s\" given", function_name, ZSTR_VAL(name));
-					zend_string_release_ex(name, false);
+					zend_tmp_string_release(tmp_str);
 					goto cleanup;
 				}
 				zend_string *lcname = zend_string_tolower(name);
 				zend_hash_add_empty_element(class_hash, lcname);
-		        zend_string_release_ex(name, false);
 		        zend_string_release_ex(lcname, false);
+		        zend_tmp_string_release(tmp_str);
 			} ZEND_HASH_FOREACH_END();
 		}
 		php_var_unserialize_set_allowed_classes(var_hash, class_hash);
diff '--color=auto' -Naur a/ext/tidy/config.m4 b/ext/tidy/config.m4
--- a/ext/tidy/config.m4	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/tidy/config.m4	2025-11-18 21:43:27.193921631 +0000
@@ -57,19 +57,34 @@
     [],
     [-L$TIDY_LIBDIR])
 
-  dnl The tidyOptGetCategory function (added in libtidy 5.4.0) if only useable
-  dnl if TidyInternalCategory (added in libtidy 5.6.0) is also present.
-  PHP_CHECK_LIBRARY([$TIDY_LIB_NAME], [tidyInternalCategory],
-    [AC_DEFINE([HAVE_TIDYOPTGETCATEGORY], [1],
-      [Define to 1 if Tidy library has the 'tidyOptGetCategory' function.])],
-    [],
-    [-L$TIDY_LIBDIR])
-
   PHP_ADD_LIBRARY_WITH_PATH([$TIDY_LIB_NAME],
     [$TIDY_LIBDIR],
     [TIDY_SHARED_LIBADD])
   PHP_ADD_INCLUDE([$TIDY_INCDIR])
 
+  old_CPPFLAGS=$CPPFLAGS
+  CPPFLAGS=-I$TIDY_INCDIR
+
+  dnl The tidyOptGetCategory function (added in tidy-html5 5.4.0) is only
+  dnl useable if TidyInternalCategory (added in tidy-html5 5.6.0) is also
+  dnl present.
+  AC_CACHE_CHECK([for tidyOptGetCategory], [php_ac_cv_have_tidyoptgetcategory],
+  [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <tidy.h>],[
+     TidyDoc doc = tidyCreate();
+     TidyOption badopt = tidyGetOptionByName(doc, "<bad>");
+     Bool v = (tidyOptGetCategory(badopt) == TidyInternalCategory);
+     (void)v;
+     tidyRelease(doc);
+    ])],
+    [php_ac_cv_have_tidyoptgetcategory=yes],
+    [php_ac_cv_have_tidyoptgetcategory=no])
+  ])
+  AS_VAR_IF([php_ac_cv_have_tidyoptgetcategory], [yes],
+    [AC_DEFINE([HAVE_TIDYOPTGETCATEGORY], [1],
+      [Define to 1 if tidyOptGetCategory is available.])])
+
+  CPPFLAGS=$old_CPPFLAGS
+
   dnl Add -Wno-ignored-qualifiers as this is an issue upstream. Fixed in
   dnl tidy-html5 5.7.20: https://github.com/htacg/tidy-html5/issues/866
   PHP_NEW_EXTENSION([tidy],
diff '--color=auto' -Naur a/ext/tidy/tidy.c b/ext/tidy/tidy.c
--- a/ext/tidy/tidy.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/tidy/tidy.c	2025-11-18 21:43:27.194089258 +0000
@@ -447,7 +447,7 @@
 				efree(intern->ptdoc->errbuf);
 				tidyRelease(intern->ptdoc->doc);
 				efree(intern->ptdoc);
-				efree(intern);
+				/* TODO: convert to exception */
 				php_error_docref(NULL, E_ERROR, "Could not set Tidy error buffer");
 			}
 
diff '--color=auto' -Naur a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c
--- a/ext/xmlreader/php_xmlreader.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/xmlreader/php_xmlreader.c	2025-11-18 21:43:27.194654254 +0000
@@ -502,12 +502,7 @@
 
 /* {{{ php_xmlreader_set_relaxng_schema */
 static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int type) {
-#ifdef LIBXML_SCHEMAS_ENABLED
-	zval *id;
 	size_t source_len = 0;
-	int retval = -1;
-	xmlreader_object *intern;
-	xmlRelaxNGPtr schema = NULL;
 	char *source;
 
 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "p!", &source, &source_len) == FAILURE) {
@@ -518,11 +513,13 @@
 		zend_argument_must_not_be_empty_error(1);
 		RETURN_THROWS();
 	}
-
-	id = ZEND_THIS;
-
-	intern = Z_XMLREADER_P(id);
+	
+#ifdef LIBXML_SCHEMAS_ENABLED
+	xmlreader_object *intern = Z_XMLREADER_P(ZEND_THIS);
 	if (intern->ptr) {
+		int retval = -1;
+		xmlRelaxNGPtr schema = NULL;
+
 		if (source) {
 			schema =  _xmlreader_get_relaxNG(source, source_len, type, NULL, NULL);
 			if (schema) {
@@ -1064,11 +1061,7 @@
 /* {{{ Use W3C XSD schema to validate the document as it is processed. Activation is only possible before the first Read(). */
 PHP_METHOD(XMLReader, setSchema)
 {
-#ifdef LIBXML_SCHEMAS_ENABLED
-	zval *id;
 	size_t source_len = 0;
-	int retval = -1;
-	xmlreader_object *intern;
 	char *source;
 
 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "p!", &source, &source_len) == FAILURE) {
@@ -1079,13 +1072,12 @@
 		zend_argument_must_not_be_empty_error(1);
 		RETURN_THROWS();
 	}
-
-	id = ZEND_THIS;
-
-	intern = Z_XMLREADER_P(id);
+	
+#ifdef LIBXML_SCHEMAS_ENABLED
+	xmlreader_object *intern = Z_XMLREADER_P(ZEND_THIS);
 	if (intern && intern->ptr) {
 		PHP_LIBXML_SANITIZE_GLOBALS(schema);
-		retval = xmlTextReaderSchemaValidate(intern->ptr, source);
+		int retval = xmlTextReaderSchemaValidate(intern->ptr, source);
 		PHP_LIBXML_RESTORE_GLOBALS(schema);
 
 		if (retval == 0) {
diff '--color=auto' -Naur a/ext/zip/php_zip.c b/ext/zip/php_zip.c
--- a/ext/zip/php_zip.c	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/zip/php_zip.c	2025-11-18 21:43:27.195227947 +0000
@@ -1838,6 +1838,11 @@
 				}
 #ifdef HAVE_ENCRYPTION
 				if (opts.enc_method >= 0) {
+					if (UNEXPECTED(zip_file_set_encryption(ze_obj->za, ze_obj->last_id, ZIP_EM_NONE, NULL) < 0)) {
+						zend_array_destroy(Z_ARR_P(return_value));
+						php_error_docref(NULL, E_WARNING, "password reset failed");
+						RETURN_FALSE;
+					}
 					if (zip_file_set_encryption(ze_obj->za, ze_obj->last_id, opts.enc_method, opts.enc_password)) {
 						zend_array_destroy(Z_ARR_P(return_value));
 						RETURN_FALSE;
diff '--color=auto' -Naur a/ext/zip/tests/oo_addglob_leak.phpt b/ext/zip/tests/oo_addglob_leak.phpt
--- a/ext/zip/tests/oo_addglob_leak.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/ext/zip/tests/oo_addglob_leak.phpt	2025-11-18 21:43:27.195566281 +0000
@@ -0,0 +1,51 @@
+--TEST--
+ZipArchive::addGlob() method leaking after several calls when encryption is set.
+--EXTENSIONS--
+zip
+--SKIPIF--
+<?php
+if (!method_exists('ZipArchive', 'setEncryptionName')) die('skip encrytion not supported');
+if(!defined("GLOB_BRACE")) die ('skip requires GLOB_BRACE');
+?>
+--FILE--
+<?php
+$dirname = __DIR__ . '/';
+include $dirname . 'utils.inc';
+
+$dirname = __DIR__ . '/__tmp_oo_addglob2/';
+$file = $dirname . 'test.zip';
+
+@mkdir($dirname);
+copy(__FILE__, $dirname . 'foo.txt');
+copy(__FILE__, $dirname . 'bar.txt');
+
+$zip = new ZipArchive();
+if (!$zip->open($file, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
+        exit('failed');
+}
+
+$options = [
+    'remove_all_path' => true,
+    'comp_method' => ZipArchive::CM_STORE,
+    'comp_flags' => 5,
+    'enc_method' => ZipArchive::EM_AES_256,
+    'enc_password' => 'secret',
+];
+var_dump($zip->addGlob($dirname . 'bar.*', GLOB_BRACE, $options));
+var_dump($zip->addGlob($dirname . 'bar.*', GLOB_BRACE, $options));
+?>
+--CLEAN--
+<?php
+$dirname = __DIR__ . '/';
+include $dirname . 'utils.inc';
+rmdir_rf(__DIR__ . '/__tmp_oo_addglob2/');
+?>
+--EXPECTF--
+array(1) {
+  [0]=>
+  string(%d) "%s"
+}
+array(1) {
+  [0]=>
+  string(%d) "%s"
+}
diff '--color=auto' -Naur a/ext/zlib/tests/zlib_wrapper_flock_basic.phpt b/ext/zlib/tests/zlib_wrapper_flock_basic.phpt
--- a/ext/zlib/tests/zlib_wrapper_flock_basic.phpt	2025-10-21 19:23:55.000000000 +0000
+++ b/ext/zlib/tests/zlib_wrapper_flock_basic.phpt	2025-11-18 21:43:27.196526459 +0000
@@ -4,7 +4,7 @@
 zlib
 --FILE--
 <?php
-$f = __DIR__."/004.txt.gz";
+$f = __DIR__."/zlib_flock.txt.gz";
 $h = gzopen($f,'r');
 var_dump(flock($h, LOCK_SH));
 gzclose($h);
diff '--color=auto' -Naur a/main/php_version.h b/main/php_version.h
--- a/main/php_version.h	2025-10-21 19:23:55.000000000 +0000
+++ b/main/php_version.h	2025-11-18 21:47:41.919656895 +0000
@@ -2,7 +2,7 @@
 /* edit configure.ac to change version number */
 #define PHP_MAJOR_VERSION 8
 #define PHP_MINOR_VERSION 4
-#define PHP_RELEASE_VERSION 14
+#define PHP_RELEASE_VERSION 15
 #define PHP_EXTRA_VERSION ""
-#define PHP_VERSION "8.4.14"
-#define PHP_VERSION_ID 80414
+#define PHP_VERSION "8.4.15"
+#define PHP_VERSION_ID 80415
diff '--color=auto' -Naur a/main/php_version.h.orig b/main/php_version.h.orig
--- a/main/php_version.h.orig	1970-01-01 00:00:00.000000000 +0000
+++ b/main/php_version.h.orig	2025-11-18 21:42:38.512935887 +0000
@@ -0,0 +1,8 @@
+/* automatically generated by configure */
+/* edit configure.ac to change version number */
+#define PHP_MAJOR_VERSION 8
+#define PHP_MINOR_VERSION 4
+#define PHP_RELEASE_VERSION 14
+#define PHP_EXTRA_VERSION ""
+#define PHP_VERSION "8.4.14"
+#define PHP_VERSION_ID 80414
diff '--color=auto' -Naur a/main/streams/xp_socket.c b/main/streams/xp_socket.c
--- a/main/streams/xp_socket.c	2025-10-21 19:23:55.000000000 +0000
+++ b/main/streams/xp_socket.c	2025-11-18 21:43:27.196881930 +0000
@@ -858,7 +858,7 @@
 static inline int php_tcp_sockop_accept(php_stream *stream, php_netstream_data_t *sock,
 		php_stream_xport_param *xparam STREAMS_DC)
 {
-	int clisock;
+	php_socket_t clisock;
 	bool nodelay = 0;
 	zval *tmpzval = NULL;
 
@@ -879,7 +879,7 @@
 		&xparam->outputs.error_code,
 		nodelay);
 
-	if (clisock >= 0) {
+	if (clisock != SOCK_ERR) {
 		php_netstream_data_t *clisockdata = (php_netstream_data_t*) emalloc(sizeof(*clisockdata));
 
 		memcpy(clisockdata, sock, sizeof(*clisockdata));
diff '--color=auto' -Naur a/run-tests.php b/run-tests.php
--- a/run-tests.php	2025-10-21 19:23:55.000000000 +0000
+++ b/run-tests.php	2025-11-18 21:43:27.197566307 +0000
@@ -2805,6 +2805,11 @@
     if ($test->hasSection('FLAKY')) {
         return true;
     }
+    if ($test->hasSection('SKIPIF')) {
+        if (strpos($test->getSection('SKIPIF'), 'SKIP_PERF_SENSITIVE') !== false) {
+            return true;
+        }
+    }
     if (!$test->hasSection('FILE')) {
         return false;
     }
diff '--color=auto' -Naur a/sapi/cgi/tests/auto_globals_no_jit.phpt b/sapi/cgi/tests/auto_globals_no_jit.phpt
--- a/sapi/cgi/tests/auto_globals_no_jit.phpt	1970-01-01 00:00:00.000000000 +0000
+++ b/sapi/cgi/tests/auto_globals_no_jit.phpt	2025-11-18 21:43:27.198756299 +0000
@@ -0,0 +1,18 @@
+--TEST--
+CGI with auto_globals_jit=0
+--INI--
+auto_globals_jit=0
+variables_order="EGPCS"
+--CGI--
+--ENV--
+FOO=BAR
+--FILE--
+<?php
+var_dump($_SERVER['FOO']);
+var_dump($_ENV['FOO']);
+var_dump(getenv('FOO'));
+?>
+--EXPECT--
+string(3) "BAR"
+string(3) "BAR"
+string(3) "BAR"
diff '--color=auto' -Naur a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c
--- a/sapi/fpm/fpm/fpm_status.c	2025-10-21 19:23:55.000000000 +0000
+++ b/sapi/fpm/fpm/fpm_status.c	2025-11-18 21:43:27.198892746 +0000
@@ -47,93 +47,76 @@
 
 int fpm_status_export_to_zval(zval *status)
 {
-	struct fpm_scoreboard_s scoreboard, *scoreboard_p;
+	struct fpm_scoreboard_s *scoreboard_p;
+	struct fpm_scoreboard_proc_s *proc_p;
 	zval fpm_proc_stats, fpm_proc_stat;
 	time_t now_epoch;
 	struct timeval duration, now;
 	double cpu;
 	int i;
 
-	scoreboard_p = fpm_scoreboard_acquire(NULL, 1);
-	if (!scoreboard_p) {
-		zlog(ZLOG_NOTICE, "[pool (unknown)] status: scoreboard already in use.");
-		return -1;
-	}
-
-	/* copy the scoreboard not to bother other processes */
-	scoreboard = *scoreboard_p;
-	struct fpm_scoreboard_proc_s *procs = safe_emalloc(
-			sizeof(struct fpm_scoreboard_proc_s), scoreboard.nprocs, 0);
-
-	struct fpm_scoreboard_proc_s *proc_p;
-	for(i=0; i<scoreboard.nprocs; i++) {
-		proc_p = fpm_scoreboard_proc_acquire(scoreboard_p, i, 1);
-		if (!proc_p){
-			procs[i].used=-1;
-			continue;
-		}
-		procs[i] = *proc_p;
-		fpm_scoreboard_proc_release(proc_p);
-	}
-	fpm_scoreboard_release(scoreboard_p);
+	scoreboard_p = fpm_scoreboard_copy(NULL, 1);
 
 	now_epoch = time(NULL);
 	fpm_clock_get(&now);
 
 	array_init(status);
-	add_assoc_string(status, "pool", scoreboard.pool);
-	add_assoc_string(status, "process-manager", PM2STR(scoreboard.pm));
-	add_assoc_long(status, "start-time", scoreboard.start_epoch);
-	add_assoc_long(status, "start-since", now_epoch - scoreboard.start_epoch);
-	add_assoc_long(status, "accepted-conn", scoreboard.requests);
-	add_assoc_long(status, "listen-queue", scoreboard.lq);
-	add_assoc_long(status, "max-listen-queue", scoreboard.lq_max);
-	add_assoc_long(status, "listen-queue-len", scoreboard.lq_len);
-	add_assoc_long(status, "idle-processes", scoreboard.idle);
-	add_assoc_long(status, "active-processes", scoreboard.active);
-	add_assoc_long(status, "total-processes", scoreboard.idle + scoreboard.active);
-	add_assoc_long(status, "max-active-processes", scoreboard.active_max);
-	add_assoc_long(status, "max-children-reached", scoreboard.max_children_reached);
-	add_assoc_long(status, "slow-requests", scoreboard.slow_rq);
-	add_assoc_long(status, "memory-peak", scoreboard.memory_peak);
+	add_assoc_string(status, "pool",  scoreboard_p->pool);
+	add_assoc_string(status, "process-manager", PM2STR( scoreboard_p->pm));
+	add_assoc_long(status, "start-time",  scoreboard_p->start_epoch);
+	add_assoc_long(status, "start-since", now_epoch -  scoreboard_p->start_epoch);
+	add_assoc_long(status, "accepted-conn",  scoreboard_p->requests);
+	add_assoc_long(status, "listen-queue",  scoreboard_p->lq);
+	add_assoc_long(status, "max-listen-queue",  scoreboard_p->lq_max);
+	add_assoc_long(status, "listen-queue-len",  scoreboard_p->lq_len);
+	add_assoc_long(status, "idle-processes",  scoreboard_p->idle);
+	add_assoc_long(status, "active-processes",  scoreboard_p->active);
+	add_assoc_long(status, "total-processes",  scoreboard_p->idle +  scoreboard_p->active);
+	add_assoc_long(status, "max-active-processes",  scoreboard_p->active_max);
+	add_assoc_long(status, "max-children-reached",  scoreboard_p->max_children_reached);
+	add_assoc_long(status, "slow-requests",  scoreboard_p->slow_rq);
+	add_assoc_long(status, "memory-peak",  scoreboard_p->memory_peak);
 
 	array_init(&fpm_proc_stats);
-	for(i=0; i<scoreboard.nprocs; i++) {
-		if (!procs[i].used) {
+	for(i = 0; i < scoreboard_p->nprocs; i++) {
+		proc_p = &scoreboard_p->procs[i];
+		if (!proc_p->used) {
 			continue;
 		}
-		proc_p = &procs[i];
 		/* prevent NaN */
-		if (procs[i].cpu_duration.tv_sec == 0 && procs[i].cpu_duration.tv_usec == 0) {
+		if (proc_p->cpu_duration.tv_sec == 0 && proc_p->cpu_duration.tv_usec == 0) {
 			cpu = 0.;
 		} else {
-			cpu = (procs[i].last_request_cpu.tms_utime + procs[i].last_request_cpu.tms_stime + procs[i].last_request_cpu.tms_cutime + procs[i].last_request_cpu.tms_cstime) / fpm_scoreboard_get_tick() / (procs[i].cpu_duration.tv_sec + procs[i].cpu_duration.tv_usec / 1000000.) * 100.;
+			cpu = (proc_p->last_request_cpu.tms_utime + proc_p->last_request_cpu.tms_stime + proc_p->last_request_cpu.tms_cutime +
+					proc_p->last_request_cpu.tms_cstime) / fpm_scoreboard_get_tick() /
+					(proc_p->cpu_duration.tv_sec + proc_p->cpu_duration.tv_usec / 1000000.) * 100.;
 		}
 
 		array_init(&fpm_proc_stat);
-		add_assoc_long(&fpm_proc_stat, "pid", procs[i].pid);
-		add_assoc_string(&fpm_proc_stat, "state", fpm_request_get_stage_name(procs[i].request_stage));
-		add_assoc_long(&fpm_proc_stat, "start-time", procs[i].start_epoch);
-		add_assoc_long(&fpm_proc_stat, "start-since", now_epoch - procs[i].start_epoch);
-		add_assoc_long(&fpm_proc_stat, "requests", procs[i].requests);
-		if (procs[i].request_stage == FPM_REQUEST_ACCEPTING) {
-			duration = procs[i].duration;
+		add_assoc_long(&fpm_proc_stat, "pid", proc_p->pid);
+		add_assoc_string(&fpm_proc_stat, "state", fpm_request_get_stage_name(proc_p->request_stage));
+		add_assoc_long(&fpm_proc_stat, "start-time", proc_p->start_epoch);
+		add_assoc_long(&fpm_proc_stat, "start-since", now_epoch - proc_p->start_epoch);
+		add_assoc_long(&fpm_proc_stat, "requests", proc_p->requests);
+		if (proc_p->request_stage == FPM_REQUEST_ACCEPTING) {
+			duration = proc_p->duration;
 		} else {
-			timersub(&now, &procs[i].accepted, &duration);
+			timersub(&now, &proc_p->accepted, &duration);
 		}
 		add_assoc_long(&fpm_proc_stat, "request-duration", duration.tv_sec * 1000000UL + duration.tv_usec);
-		add_assoc_string(&fpm_proc_stat, "request-method", procs[i].request_method[0] != '\0' ? procs[i].request_method : "-");
-		add_assoc_string(&fpm_proc_stat, "request-uri", procs[i].request_uri);
-		add_assoc_string(&fpm_proc_stat, "query-string", procs[i].query_string);
-		add_assoc_long(&fpm_proc_stat, "request-length", procs[i].content_length);
-		add_assoc_string(&fpm_proc_stat, "user", procs[i].auth_user[0] != '\0' ? procs[i].auth_user : "-");
-		add_assoc_string(&fpm_proc_stat, "script", procs[i].script_filename[0] != '\0' ? procs[i].script_filename : "-");
-		add_assoc_double(&fpm_proc_stat, "last-request-cpu", procs[i].request_stage == FPM_REQUEST_ACCEPTING ? cpu : 0.);
-		add_assoc_long(&fpm_proc_stat, "last-request-memory", procs[i].request_stage == FPM_REQUEST_ACCEPTING ? procs[i].memory : 0);
+		add_assoc_string(&fpm_proc_stat, "request-method", proc_p->request_method[0] != '\0' ? proc_p->request_method : "-");
+		add_assoc_string(&fpm_proc_stat, "request-uri", proc_p->request_uri);
+		add_assoc_string(&fpm_proc_stat, "query-string", proc_p->query_string);
+		add_assoc_long(&fpm_proc_stat, "request-length", proc_p->content_length);
+		add_assoc_string(&fpm_proc_stat, "user", proc_p->auth_user[0] != '\0' ? proc_p->auth_user : "-");
+		add_assoc_string(&fpm_proc_stat, "script", proc_p->script_filename[0] != '\0' ? proc_p->script_filename : "-");
+		add_assoc_double(&fpm_proc_stat, "last-request-cpu", proc_p->request_stage == FPM_REQUEST_ACCEPTING ? cpu : 0.);
+		add_assoc_long(&fpm_proc_stat, "last-request-memory", proc_p->request_stage == FPM_REQUEST_ACCEPTING ? proc_p->memory : 0);
 		add_next_index_zval(&fpm_proc_stats, &fpm_proc_stat);
 	}
 	add_assoc_zval(status, "procs", &fpm_proc_stats);
-	efree(procs);
+
+	fpm_scoreboard_free_copy(scoreboard_p);
 
 	return 0;
 }
diff '--color=auto' -Naur a/sapi/fpm/tests/bug74083-concurrent-reload.phpt b/sapi/fpm/tests/bug74083-concurrent-reload.phpt
--- a/sapi/fpm/tests/bug74083-concurrent-reload.phpt	2025-10-21 19:23:55.000000000 +0000
+++ b/sapi/fpm/tests/bug74083-concurrent-reload.phpt	2025-11-18 21:43:27.199378213 +0000
@@ -4,6 +4,7 @@
 <?php
 include "skipif.inc";
 if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
+if (getenv("GITHUB_ACTIONS") && PHP_OS_FAMILY === "Darwin") die("skip Potential cause for GitHub Actions crash");
 ?>
 --FILE--
 <?php
diff '--color=auto' -Naur a/sapi/fpm/tests/bug76601-reload-child-signals.phpt b/sapi/fpm/tests/bug76601-reload-child-signals.phpt
--- a/sapi/fpm/tests/bug76601-reload-child-signals.phpt	2025-10-21 19:23:55.000000000 +0000
+++ b/sapi/fpm/tests/bug76601-reload-child-signals.phpt	2025-11-18 21:43:27.199533767 +0000
@@ -4,6 +4,7 @@
 <?php
 include "skipif.inc";
 if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
+if (getenv("GITHUB_ACTIONS") && PHP_OS_FAMILY === "Darwin") die("skip Potential cause for GitHub Actions crash");
 ?>
 --FILE--
 <?php
diff '--color=auto' -Naur a/win32/select.c b/win32/select.c
--- a/win32/select.c	2025-10-21 19:23:55.000000000 +0000
+++ b/win32/select.c	2025-11-18 21:43:27.199673911 +0000
@@ -62,8 +62,10 @@
 	/* build an array of handles for non-sockets */
 	for (i = 0; (uint32_t)i < max_fd; i++) {
 		if (SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) || SAFE_FD_ISSET(i, efds)) {
-			handles[n_handles] = (HANDLE)(uintptr_t)_get_osfhandle(i);
-			if (handles[n_handles] == INVALID_HANDLE_VALUE) {
+			int _type;
+			int _len = sizeof(_type);
+
+			if (getsockopt((SOCKET)i, SOL_SOCKET, SO_TYPE, (char*)&_type, &_len) == 0 || WSAGetLastError() != WSAENOTSOCK) {
 				/* socket */
 				if (SAFE_FD_ISSET(i, rfds)) {
 					FD_SET((uint32_t)i, &sock_read);
@@ -78,8 +80,11 @@
 					sock_max_fd = i;
 				}
 			} else {
-				handle_slot_to_fd[n_handles] = i;
-				n_handles++;
+				handles[n_handles] = (HANDLE)(uintptr_t)_get_osfhandle(i);
+				if (handles[n_handles] != INVALID_HANDLE_VALUE) {
+					handle_slot_to_fd[n_handles] = i;
+					n_handles++;
+				}
 			}
 		}
 	}
