DDC-2785: spl_object_hash_collisions #3533

Open
doctrinebot opened this Issue Nov 8, 2013 · 4 comments

2 participants

@doctrinebot

Jira issue originally created by user flack:

After reading DDC-1896 and DDC-136, I'm not exactly sure if this qualifies as a bug, but anyways, here's my code to reproduce:

    public function test*hash*collision()
    {
        $counter = 0;
        do
        {
            $object = $this->create_object();
            $counter<ins></ins>;
            if ($counter > 1000)
            {
                //mark as skipped ? (I never hit this on PHP 5.3 at least)
                break;
            }
        }
        while ($object === false);

        // This fails with "Failed asserting that 1 matches expected 2."
        $this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE*NEW, $this->*em->getUnitOfWork()->getEntityState($object));
    }

    private function create_object()
    {
        static $hashes = array();
        $phone = new CmsPhonenumber();
        $phone->phonenumber = "1234";
        $hash = spl*object*hash($phone);
        $this->_em->persist($phone);

        if (!array*key*exists($hash, $hashes))
        {
            $hashes[$hash] = true;
            $this->_em->flush($phone);
            $this->_em->remove($phone);
            $this->_em->flush($phone);
            return false;
        }
        // Bingo! We have a new object with a recycled hash
        return $phone;
    }
@doctrinebot

Comment created by @ocramius:

Are you able to reproduce the test also without statics?

@doctrinebot

Comment created by flack:

Yes, if I switch to $this->hashes (private $hashes = array()), the result is the same

@doctrinebot

Comment created by flack:

Here's the complete test without statics & according to Doctrine CS (AFAICT):

<?php

namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\Tests\Models\CMS\CmsPhonenumber;

require*once __DIR_* . '/../../../TestInit.php';

/****
 * @group [DDC-2785](http://www.doctrine-project.org/jira/browse/DDC-2785)
 */
class DDC2785Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
    public function setUp()
    {
        $this->useModelSet('cms');
        parent::setUp();
    }

    private $hashes = array();

    public function testIssue()
    {
        $counter = 0;
        do
        {
            $object = $this->createObject();
            $counter<ins></ins>;
            if ($counter > 1000)
            {
                //mark as skipped ? (I never hit this on PHP 5.3 at least)
                break;
            }
        }
        while ($object === false);

        $this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE*NEW, $this->*em->getUnitOfWork()->getEntityState($object));
    }

    private function createObject()
    {
        $phone = new CmsPhonenumber();
        $phone->phonenumber = "1234";
        $hash = spl*object*hash($phone);
        $this->_em->persist($phone);

        if (!array*key*exists($hash, $this->hashes))
        {
            $this->hashes[$hash] = true;
            $this->_em->flush();
            $this->_em->remove($phone);
            $this->_em->flush();
            return false;
        }

        return $phone;
    }
}

I can try and send this as a pull request, if it helps

@doctrinebot

Comment created by @doctrinebot:

A related Github Pull-Request [GH-843] was labeled:
#843

@beberlei beberlei was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment