Skip to content

Commit ab7c3b1

Browse files
committed
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3: Fix GH-16957: Assertion failure in array_shift with self-referencing array
2 parents 8ea042d + f1fc4e8 commit ab7c3b1

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ PHP NEWS
4343
- Standard:
4444
. Fixed bug GH-16905 (Internal iterator functions can't handle UNDEF
4545
properties). (nielsdos)
46+
. Fixed bug GH-16957 (Assertion failure in array_shift with
47+
self-referencing array). (nielsdos)
4648

4749
- Streams:
4850
. Fixed network connect poll interuption handling. (Jakub Zelenka)

ext/standard/array.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3632,7 +3632,8 @@ PHP_FUNCTION(array_shift)
36323632
}
36333633
idx++;
36343634
}
3635-
RETVAL_COPY_DEREF(val);
3635+
RETVAL_COPY_VALUE(val);
3636+
ZVAL_UNDEF(val);
36363637

36373638
/* Delete the first value */
36383639
zend_hash_packed_del_val(Z_ARRVAL_P(stack), val);
@@ -3686,7 +3687,8 @@ PHP_FUNCTION(array_shift)
36863687
}
36873688
idx++;
36883689
}
3689-
RETVAL_COPY_DEREF(val);
3690+
RETVAL_COPY_VALUE(val);
3691+
ZVAL_UNDEF(val);
36903692

36913693
/* Delete the first value */
36923694
zend_hash_del_bucket(Z_ARRVAL_P(stack), p);
@@ -3710,6 +3712,10 @@ PHP_FUNCTION(array_shift)
37103712
}
37113713

37123714
zend_hash_internal_pointer_reset(Z_ARRVAL_P(stack));
3715+
3716+
if (Z_ISREF_P(return_value)) {
3717+
zend_unwrap_reference(return_value);
3718+
}
37133719
}
37143720
/* }}} */
37153721

ext/standard/tests/array/gh16957.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
GH-16957 (Assertion failure in array_shift with self-referencing array)
3+
--FILE--
4+
<?php
5+
$new_array = array(&$new_array, 1, 'two');
6+
var_dump($shifted = array_shift($new_array));
7+
var_dump($new_array);
8+
var_dump($new_array === $shifted);
9+
10+
$new_array2 = array(&$new_array2, 2 => 1, 300 => 'two');
11+
var_dump($shifted = array_shift($new_array2));
12+
var_dump($new_array2);
13+
var_dump($new_array2 === $shifted);
14+
?>
15+
--EXPECT--
16+
array(2) {
17+
[0]=>
18+
int(1)
19+
[1]=>
20+
string(3) "two"
21+
}
22+
array(2) {
23+
[0]=>
24+
int(1)
25+
[1]=>
26+
string(3) "two"
27+
}
28+
bool(true)
29+
array(2) {
30+
[0]=>
31+
int(1)
32+
[1]=>
33+
string(3) "two"
34+
}
35+
array(2) {
36+
[0]=>
37+
int(1)
38+
[1]=>
39+
string(3) "two"
40+
}
41+
bool(true)

0 commit comments

Comments
 (0)