Skip to content

Commit

Permalink
[PropertyAccess] Fix accessing dynamic properties
Browse files Browse the repository at this point in the history
  • Loading branch information
andreyserdjuk authored and fabpot committed Aug 26, 2020
1 parent fc3095f commit 47bd018
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/Symfony/Component/PropertyAccess/PropertyAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -435,10 +435,16 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid

throw $e;
}
} elseif ($object instanceof \stdClass && property_exists($object, $property)) {
$result[self::VALUE] = $object->$property;
if (isset($zval[self::REF])) {
$result[self::REF] = &$object->$property;
} elseif (property_exists($object, $property)) {
try {
$result[self::VALUE] = $object->$property;
if (isset($zval[self::REF])) {
$result[self::REF] = &$object->$property;
}
} catch (\Error $e) {
if (!$ignoreInvalidProperty) {
throw new NoSuchPropertyException(sprintf('Can\'t read protected or private property "%s" in class "%s".', $property, $class), 0, $e);
}
}
} elseif (!$ignoreInvalidProperty) {
throw new NoSuchPropertyException(sprintf('Can\'t get a way to read the property "%s" in class "%s".', $property, $class));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Symfony\Component\PropertyAccess\Tests\Fixtures;

class TestClassDynamicProperty
{
public function __construct($dynamicProperty)
{
$this->dynamicProperty = $dynamicProperty;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestAdderRemoverInvalidArgumentLength;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestAdderRemoverInvalidMethods;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClass;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassDynamicProperty;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassIsWritable;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicCall;
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicGet;
Expand Down Expand Up @@ -97,6 +98,29 @@ public function testGetValue($objectOrArray, $path, $value)
$this->assertSame($value, $this->propertyAccessor->getValue($objectOrArray, $path));
}

/**
* Test get dynamic value from object is other than \stdClass instance.
*/
public function testGetDynamicValue()
{
$value = 'dynamicPropertyValue';
$path = 'dynamicProperty';
$object = new TestClassDynamicProperty($value);

$this->assertSame($value, $this->propertyAccessor->getValue($object, $path));
}

/**
* Ensure exact exception with message was thrown on access to non-public property.
*/
public function testGetInaccessibleProperty()
{
$this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException');
$this->expectExceptionMessage(sprintf('Can\'t read protected or private property "%s" in class "%s".', 'protectedProperty', TestClass::class));

$this->propertyAccessor->getValue(new TestClass('Bernhard'), 'protectedProperty');
}

/**
* @dataProvider getPathsWithMissingProperty
*/
Expand Down

0 comments on commit 47bd018

Please sign in to comment.