php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65629 SplObjectsStorage::detach() rewinds internal pointer
Submitted: 2013-09-07 03:14 UTC Modified: 2017-10-24 05:19 UTC
Votes:7
Avg. Score:4.1 ± 0.6
Reproduced:6 of 6 (100.0%)
Same Version:3 (50.0%)
Same OS:2 (33.3%)
From: alan dot bem at gmail dot com Assigned: levim (profile)
Status: Assigned Package: SPL related
PHP Version: Irrelevant OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: alan dot bem at gmail dot com
New email:
PHP Version: OS:

 

 [2013-09-07 03:14 UTC] alan dot bem at gmail dot com
Description:
------------
It seems that SplObjectsStorage::detach() internally rewinds its array pointer.

PHP versions from 5.1.0 to 5.5.3 are affected.

Test script:
---------------
// To see this live, go to: http://3v4l.org/MAELj

<?php
class A
{
    public $val;
    public function __construct($val) { $this->val = $val; }
}
$storage = new SplObjectStorage;
for($i = 1; $i <= 10; $i++) {
	$storage->attach(new A($i));
}
$iterations = 0;
$storage->rewind();
while ($storage->valid()) {
    $iterations++;
    $object = $storage->current();
    echo 'Iteration #' . $iterations . ' with object A(' . $object->val . ')';
    $storage->next();
    if($iterations === 2 || $iterations === 8) {
        $storage->detach($object);
        echo ' - deleted Object A(' . $object->val . ') ';
    }
    echo PHP_EOL;
}
echo 'Number of iterations: ' . $iterations . PHP_EOL;

Expected result:
----------------
Iteration #1 with object A(1)
Iteration #2 with object A(2) - deleted Object A(2) 
Iteration #3 with object A(3)
Iteration #4 with object A(4)
Iteration #5 with object A(5)
Iteration #6 with object A(6)
Iteration #7 with object A(7) - deleted Object A(7) 
Iteration #8 with object A(8)
Iteration #9 with object A(9)
Iteration #10 with object A(10)
Number of iterations: 10

Actual result:
--------------
Iteration #1 with object A(1)
Iteration #2 with object A(2) - deleted Object A(2) 
Iteration #3 with object A(1)
Iteration #4 with object A(3)
Iteration #5 with object A(4)
Iteration #6 with object A(5)
Iteration #7 with object A(6)
Iteration #8 with object A(7) - deleted Object A(7) 
Iteration #9 with object A(1)
Iteration #10 with object A(3)
Iteration #11 with object A(4)
Iteration #12 with object A(5)
Iteration #13 with object A(6)
Iteration #14 with object A(8)
Iteration #15 with object A(9)
Iteration #16 with object A(10)
Number of iterations: 16

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-09-12 22:49 UTC] levim@php.net
-Status: Open +Status: Verified -Assigned To: +Assigned To: levim
 [2013-09-12 22:49 UTC] levim@php.net
Regardless of whether this is a bug, in general modifying a structure during 
iteration has undefined behavior. I will look a bit into this and see what might 
be done.
 [2013-09-21 23:02 UTC] levim@php.net
Bug #63917 is a duplicate of this one (has a phpt uploaded -- might be useful).
 [2015-07-20 10:08 UTC] bas at dmt-software dot nl
SplObjectsStorage::attach() does change the pointer too.
These operations should not change the internal pointer at all.
It's behaviour should be more similar to ArrayObject, it's less confusing that way.
 [2017-10-24 05:19 UTC] kalle@php.net
-Status: Verified +Status: Assigned
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC