Commit f47cdadfb8d for php.net

commit f47cdadfb8dba671904040d2b154ecb310ee7832
Merge: 0beb2a99d3b 7a4c6279536
Author: Weilin Du <weilindu@php.net>
Date:   Thu Sep 10 00:08:43 2026 +0800

    Merge branch 'PHP-8.5'

    * PHP-8.5:
      [skip ci] Fix NEWS entry for #23607
      Zend: Fix iterator relocation at the current element during rehash (#23607)

diff --cc NEWS
index 7c9c4f08ed1,37f27f3572c..16faf437201
--- a/NEWS
+++ b/NEWS
@@@ -1,7 -1,11 +1,11 @@@
  PHP                                                                        NEWS
  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 -?? ??? ????, PHP 8.5.12
 +?? ??? ????, PHP 8.6.0RC1

+ - Core:
+   . Fixed incorrect internal pointer and foreach iterator positions when
+     compacting arrays with holes. (Weilin Du)
+
  - DOM:
    . Fixed use-after-free when re-constructing a DOMXPath whose php:function
      registrations are freed while still reachable from the cycle collector.
diff --cc Zend/zend_hash.c
index 84751a02e7c,c90887ed7c4..4640846ecc7
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@@ -2415,8 -2406,8 +2415,8 @@@ static zend_always_inline uint32_t zend
  			idx++; p++;
  			if (EXPECTED(!HT_HAS_ITERATORS(target))) {
  				while (p != end) {
 -					if (zend_array_dup_element(source, target, target_idx, p, q, 0, static_keys, with_holes)) {
 +					if (zend_array_dup_element(source, target, target_idx, p, q, false, static_keys, with_holes)) {
- 						if (source->nInternalPointer == idx) {
+ 						if (UNEXPECTED(target->nInternalPointer > target_idx && target->nInternalPointer <= idx)) {
  							target->nInternalPointer = target_idx;
  						}
  						target_idx++; q++;
@@@ -2428,8 -2419,8 +2428,8 @@@
  				uint32_t iter_pos = zend_hash_iterators_lower_pos(target, idx);

  				while (p != end) {
 -					if (zend_array_dup_element(source, target, target_idx, p, q, 0, static_keys, with_holes)) {
 +					if (zend_array_dup_element(source, target, target_idx, p, q, false, static_keys, with_holes)) {
- 						if (source->nInternalPointer == idx) {
+ 						if (UNEXPECTED(target->nInternalPointer > target_idx && target->nInternalPointer <= idx)) {
  							target->nInternalPointer = target_idx;
  						}
  						if (UNEXPECTED(idx >= iter_pos)) {