Skip to content

Commit 4b9fbc6

Browse files
committed
Fixed bug #81587
iterator_funcs_ptr may be null for Iterators with custom get_iterator. Ideally MultipleIterator would make use of get_iterator, but this would require a large implementation change.
1 parent 34d22ac commit 4b9fbc6

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2021, PHP 8.0.14
44

5+
- SPL:
6+
. Fixed bug #81587 (MultipleIterator Segmentation fault w/ SimpleXMLElement
7+
attached). (Nikita)
8+
59
18 Nov 2021, PHP 8.0.13
610

711
- Core:

ext/spl/spl_observer.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,7 +1029,7 @@ PHP_METHOD(MultipleIterator, rewind)
10291029
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
10301030
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
10311031
it = &element->obj;
1032-
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_rewind, "rewind", NULL);
1032+
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), Z_OBJCE_P(it)->iterator_funcs_ptr ? &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_rewind : NULL, "rewind", NULL);
10331033
zend_hash_move_forward_ex(&intern->storage, &intern->pos);
10341034
}
10351035
}
@@ -1051,7 +1051,7 @@ PHP_METHOD(MultipleIterator, next)
10511051
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
10521052
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
10531053
it = &element->obj;
1054-
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_next, "next", NULL);
1054+
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), Z_OBJCE_P(it)->iterator_funcs_ptr ? &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_next : NULL, "next", NULL);
10551055
zend_hash_move_forward_ex(&intern->storage, &intern->pos);
10561056
}
10571057
}
@@ -1080,7 +1080,7 @@ PHP_METHOD(MultipleIterator, valid)
10801080
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
10811081
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
10821082
it = &element->obj;
1083-
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_valid, "valid", &retval);
1083+
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), Z_OBJCE_P(it)->iterator_funcs_ptr ? &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_valid : NULL, "valid", &retval);
10841084

10851085
if (!Z_ISUNDEF(retval)) {
10861086
valid = (Z_TYPE(retval) == IS_TRUE);
@@ -1116,7 +1116,7 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
11161116
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
11171117
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
11181118
it = &element->obj;
1119-
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_valid, "valid", &retval);
1119+
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), Z_OBJCE_P(it)->iterator_funcs_ptr ? &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_valid : NULL, "valid", &retval);
11201120

11211121
if (!Z_ISUNDEF(retval)) {
11221122
valid = Z_TYPE(retval) == IS_TRUE;
@@ -1127,9 +1127,9 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
11271127

11281128
if (valid) {
11291129
if (SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT == get_type) {
1130-
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_current, "current", &retval);
1130+
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), Z_OBJCE_P(it)->iterator_funcs_ptr ? &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_current : NULL, "current", &retval);
11311131
} else {
1132-
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_key, "key", &retval);
1132+
zend_call_method_with_0_params(Z_OBJ_P(it), Z_OBJCE_P(it), Z_OBJCE_P(it)->iterator_funcs_ptr ? &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_key : NULL, "key", &retval);
11331133
}
11341134
if (Z_ISUNDEF(retval)) {
11351135
zend_throw_exception(spl_ce_RuntimeException, "Failed to call sub iterator method", 0);

ext/spl/tests/bug81587.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Bug #81587: MultipleIterator Segmentation fault w/ SimpleXMLElement attached
3+
--SKIPIF--
4+
<?php if (!extension_loaded('simplexml')) die('skip requires simplexml'); ?>
5+
--FILE--
6+
<?php
7+
$mi = new MultipleIterator();
8+
$mi->attachIterator(new SimpleXMLElement('<x><y/></x>'));
9+
foreach ($mi as $v) {
10+
var_dump($v);
11+
}
12+
?>
13+
--EXPECT--
14+
array(1) {
15+
[0]=>
16+
object(SimpleXMLElement)#4 (0) {
17+
}
18+
}

0 commit comments

Comments
 (0)