[HttpKernel] Fix datacollector caster for reference object property

This commit is contained in:
Thomas Decaux
2024-02-26 17:33:35 -05:00
committed by Nicolas Grekas
parent fa6412804b
commit 105a29feae
4 changed files with 104 additions and 2 deletions

View File

@@ -70,9 +70,21 @@ abstract class DataCollector implements DataCollectorInterface
$casters = [
'*' => function ($v, array $a, Stub $s, $isNested) {
if (!$v instanceof Stub) {
$b = $a;
foreach ($a as $k => $v) {
if (\is_object($v) && !$v instanceof \DateTimeInterface && !$v instanceof Stub) {
$a[$k] = new CutStub($v);
if (!\is_object($v) || $v instanceof \DateTimeInterface || $v instanceof Stub) {
continue;
}
try {
$a[$k] = $s = new CutStub($v);
if ($b[$k] === $s) {
// we've hit a non-typed reference
$a[$k] = $v;
}
} catch (\TypeError $e) {
// we've hit a typed reference
}
}
}

View File

@@ -15,6 +15,8 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Tests\Fixtures\DataCollector\CloneVarDataCollector;
use Symfony\Component\HttpKernel\Tests\Fixtures\UsePropertyInDestruct;
use Symfony\Component\HttpKernel\Tests\Fixtures\WithPublicObjectProperty;
use Symfony\Component\VarDumper\Cloner\VarCloner;
class DataCollectorTest extends TestCase
@@ -35,4 +37,68 @@ class DataCollectorTest extends TestCase
$this->assertSame($filePath, $c->getData()[0]);
}
/**
* @requires PHP 8
*/
public function testClassPublicObjectProperty()
{
$parent = new WithPublicObjectProperty();
$child = new WithPublicObjectProperty();
$child->parent = $parent;
$c = new CloneVarDataCollector($child);
$c->collect(new Request(), new Response());
$this->assertNotNull($c->getData()->parent);
}
/**
* @requires PHP 8
*/
public function testClassPublicObjectPropertyAsReference()
{
$parent = new WithPublicObjectProperty();
$child = new WithPublicObjectProperty();
$child->parent = &$parent;
$c = new CloneVarDataCollector($child);
$c->collect(new Request(), new Response());
$this->assertNotNull($c->getData()->parent);
}
/**
* @requires PHP 8
*/
public function testClassUsePropertyInDestruct()
{
$parent = new UsePropertyInDestruct();
$child = new UsePropertyInDestruct();
$child->parent = $parent;
$c = new CloneVarDataCollector($child);
$c->collect(new Request(), new Response());
$this->assertNotNull($c->getData()->parent);
}
/**
* @requires PHP 8
*/
public function testClassUsePropertyAsReferenceInDestruct()
{
$parent = new UsePropertyInDestruct();
$child = new UsePropertyInDestruct();
$child->parent = &$parent;
$c = new CloneVarDataCollector($child);
$c->collect(new Request(), new Response());
$this->assertNotNull($c->getData()->parent);
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Symfony\Component\HttpKernel\Tests\Fixtures;
class UsePropertyInDestruct
{
public string $name;
public $parent = null;
public function __destruct()
{
if ($this->parent !== null) {
$this->parent->name = '';
}
}
}

View File

@@ -0,0 +1,8 @@
<?php
namespace Symfony\Component\HttpKernel\Tests\Fixtures;
class WithPublicObjectProperty
{
public ?WithPublicObjectProperty $parent = null;
}