php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81587 MultipleIterator Segmentation fault w/ SimpleXMLElement attached
Submitted: 2021-11-03 14:01 UTC Modified: 2021-11-04 09:28 UTC
From: hanskrentel at yahoo dot de Assigned:
Status: Closed Package: SPL related
PHP Version: 8.0.12 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: hanskrentel at yahoo dot de
New email:
PHP Version: OS:

 

 [2021-11-03 14:01 UTC] hanskrentel at yahoo dot de
Description:
------------
Since PHP 8.0 SimpleXMLElement is an Iterator and it is
possibe to attach it to a MultipleIterator (TypeError earlier).

Attached to a MultipleIterator and iterating the MultipleIterator makes
PHP exit code 139 (interrupted by signal 11: SIGSEGV - Segmentation fault)

Starting with PHP 8.1rc1 this is not an issue any longer.

Test script:
---------------
$mi = new MultipleIterator();
$mi->attachIterator(new SimpleXMLElement('<r/>'));
$mi->rewind();

Expected result:
----------------
Process exited with code 0

Actual result:
--------------
Output for 8.0.0 - 8.0.12: Process exited with code 139.
https://3v4l.org/DhLc0

A workaround is available: Wrapping the SimpleXMLElement inside an
IteratorIterator prevents the segmentation fault:

$mi = new MultipleIterator();
$mi->attachIterator(new IteratorIterator(new SimpleXMLElement('<r/>')));
$mi->rewind();

https://3v4l.org/C962A

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-11-03 19:19 UTC] requinix@php.net
-Status: Open +Status: Verified
 [2021-11-03 19:19 UTC] requinix@php.net
0x0000555555c77eef in zend_call_method (object=0x7ffff4481060, obj_ce=0x555556e52730, fn_proxy=0x28, function_name=0x5555566743da "rewind", function_name_len=6,
    retval_ptr=0x0, param_count=0, arg1=0x0, arg2=0x0) at /home/ubuntu/php/php-8.0.12/src/Zend/zend_interfaces.c:54
54              if (!fn_proxy || !*fn_proxy) {

(gdb) bt
#0  0x0000555555c77eef in zend_call_method (object=0x7ffff4481060, obj_ce=0x555556e52730, fn_proxy=0x28, function_name=0x5555566743da "rewind", function_name_len=6,
    retval_ptr=0x0, param_count=0, arg1=0x0, arg2=0x0) at /home/ubuntu/php/php-8.0.12/src/Zend/zend_interfaces.c:54
#1  0x00005555559f4684 in zim_MultipleIterator_rewind (execute_data=0x7ffff44140f0, return_value=0x7fffffffa740)
    at /home/ubuntu/php/php-8.0.12/src/ext/spl/spl_observer.c:1032
#2  0x0000555555bfd061 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at /home/ubuntu/php/php-8.0.12/src/Zend/zend_vm_execute.h:1755
#3  0x0000555555c6cd87 in execute_ex (ex=0x7ffff4414020) at /home/ubuntu/php/php-8.0.12/src/Zend/zend_vm_execute.h:54199
#4  0x0000555555c724e8 in zend_execute (op_array=0x7ffff445d280, return_value=0x0) at /home/ubuntu/php/php-8.0.12/src/Zend/zend_vm_execute.h:58518
#5  0x0000555555bc2e77 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/ubuntu/php/php-8.0.12/src/Zend/zend.c:1680
#6  0x0000555555b2425c in php_execute_script (primary_file=0x7fffffffcf40) at /home/ubuntu/php/php-8.0.12/src/main/main.c:2524
#7  0x0000555555cb34b7 in do_cli (argc=2, argv=0x555556c2df00) at /home/ubuntu/php/php-8.0.12/src/sapi/cli/php_cli.c:949
#8  0x0000555555cb4513 in main (argc=2, argv=0x555556c2df00) at /home/ubuntu/php/php-8.0.12/src/sapi/cli/php_cli.c:1337
 [2021-11-04 09:28 UTC] nikic@php.net
The fix in PHP 8.1 here is somewhat accidental: When class declarations were migrated to stubs, the declaration order was changed: Now we generally always implement Iterator before assigning get_iterator. This means that the code in zend_implement_iterator that avoids initializing iterator_funcs_ptr for custom get_iterator will no longer trigger in practice, and iterator_funcs_ptr will always be allocated. To avoid confusion and subtle dependency on class initialization order, the special handling there should probably get dropped and iterator_funcs_ptr be initialized unconditionally.

As far as MultipleIterator is concerned, I'd say the proper fix here would be to go through the get_iterator interface rather than manually calling Iterator methods. But as MultipleIterator is based on SplObjectStorage in a weird way, we can't easily do this. So we should just check whether iterator_funcs_ptr is null  for PHP 8.0.
 [2021-11-04 09:39 UTC] git@php.net
Automatic comment on behalf of nikic
Revision: https://github.com/php/php-src/commit/4b9fbc6627cc17869fb43826e30299f6e716178b
Log: Fixed bug #81587
 [2021-11-04 09:39 UTC] git@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Apr 02 01:01:29 2025 UTC