10000 bug #37622 [PropertyAccess] Fix accessing dynamic properties (andreys… · symfony/symfony@92cb709 · GitHub
[go: up one dir, main page]

Skip to content

Commit 92cb709

Browse files
committed
bug #37622 [PropertyAccess] Fix accessing dynamic properties (andreyserdjuk)
This PR was submitted for the master branch but it was squashed and merged into the 5.1 branch instead. Discussion ---------- [PropertyAccess] Fix accessing dynamic properties | Q | A | ------------- | --- | Branch? | 5.1 (to be switched when merging) | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tickets | Fix #37026 <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT | Doc PR | no <!-- required for new features --> <!-- Replace this notice by a short README for your feature/bugfix. This will help people understand your PR and can be used as a start for the documentation. Additionally (see https://symfony.com/releases): - Always add tests and ensure they pass. - Never break backward compatibility (see https://symfony.com/bc). - Bug fixes must be submitted against the lowest maintained branch where they apply (lowest branches are regularly merged to upper ones so they get the fixes too.) - Features and deprecations must be submitted against branch master. --> Commits ------- 47bd018 [PropertyAccess] Fix accessing dynamic properties
2 parents fc3095f + 47bd018 commit 92cb709

File tree

3 files changed

+45
-4
lines changed

3 files changed

+45
-4
lines changed

src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,16 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid
435435

436436
throw $e;
437437
}
438-
} elseif ($object instanceof \stdClass && property_exists($object, $property)) {
439-
$result[self::VALUE] = $object->$property;
440-
if (isset($zval[self::REF])) {
441-
$result[self::REF] = &$object->$property;
438+
} elseif (property_exists($object, $property)) {
439+
try {
440+
$result[self::VALUE] = $object->$property;
441+
if (isset($zval[self::REF])) {
442+
$result[self::REF] = &$object->$property;
443+
}
444+
} catch (\Error $e) {
445+
if (!$ignoreInvalidProperty) {
446+
throw new NoSuchPropertyException(sprintf('Can\'t read protected or private property "%s" in class "%s".', $property, $class), 0, $e);
447+
}
442448
}
443449
} elseif (!$ignoreInvalidProperty) {
444450
throw new NoSuchPropertyException(sprintf('Can\'t get a way to read the property "%s" in class "%s".', $property, $class));
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symfony\Component\PropertyAccess\Tests\Fixtures;
4+
5+
class TestClassDynamicProperty
6+
{
7+
public function __construct($dynamicProperty)
8+
{
9+
$this->dynamicProperty = $dynamicProperty;
10+
}
11+
}

src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestAdderRemoverInvalidArgumentLength;
2222
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestAdderRemoverInvalidMethods;
2323
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClass;
24+
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassDynamicProperty;
2425
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassIsWritable;
2526
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicCall;
2627
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestClassMagicGet;
@@ -97,6 +98,29 @@ public function testGetValue($objectOrArray, $path, $value)
9798
$this->assertSame($value, $this->propertyAccessor->getValue($objectOrArray, $path));
9899
}
99100

101+
/**
102+
* Test get dynamic value from object is other than \stdClass instance.
103+
*/
104+
public function testGetDynamicValue()
105+
{
106+
$value = 'dynamicPropertyValue';
107+
$path = 'dynamicProperty';
108+
$object = new TestClassDynamicProperty($value);
109+
110+
$this->assertSame($value, $this->propertyAccessor->getValue($object, $path));
111+
}
112+
113+
/**
114+
* Ensure exact exception with message was thrown on access to non-public property.
115+
*/
116+
public function testGetInaccessibleProperty()
117+
{
118+
$this->expectException('Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException');
119+
$this->expectExceptionMessage(sprintf('Can\'t read protected or private property "%s" in class "%s".', 'protectedProperty', TestClass::class));
120+
121+
$this->propertyAccessor->getValue(new TestClass('Bernhard'), 'protectedProperty');
122+
}
123+
100124
/**
101125
* @dataProvider getPathsWithMissingProperty
102126
*/

0 commit comments

Comments
 (0)
0