Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ef4dcdb

Browse filesBrowse files
committed
bug #35546 [Validator] check for __get method existence if property is uninitialized (alekitto)
This PR was merged into the 3.4 branch. Discussion ---------- [Validator] check for __get method existence if property is uninitialized | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #35544 | License | MIT Resolve bug #35544. On PHP 7.4, check if object implements `__get` magic method if property is reported as uninitialized before returning null. Commits ------- 427bc3a [Validator] try to call __get method if property is uninitialized
2 parents af46fd6 + 427bc3a commit ef4dcdb
Copy full SHA for ef4dcdb

File tree

3 files changed

+48
-2
lines changed
Filter options

3 files changed

+48
-2
lines changed

‎src/Symfony/Component/Validator/Mapping/PropertyMetadata.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Mapping/PropertyMetadata.php
+15-2Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,21 @@ public function getPropertyValue($object)
5050
{
5151
$reflProperty = $this->getReflectionMember($object);
5252

53-
if (\PHP_VERSION_ID >= 70400 && !$reflProperty->isInitialized($object)) {
54-
return null;
53+
if (\PHP_VERSION_ID >= 70400 && $reflProperty->hasType() && !$reflProperty->isInitialized($object)) {
54+
// There is no way to check if a property has been unset or if it is uninitialized.
55+
// When trying to access an uninitialized property, __get method is triggered.
56+
57+
// If __get method is not present, no fallback is possible
58+
// Otherwise we need to catch an Error in case we are trying to access an uninitialized but set property.
59+
if (!method_exists($object, '__get')) {
60+
return null;
61+
}
62+
63+
try {
64+
return $reflProperty->getValue($object);
65+
} catch (\Error $e) {
66+
return null;
67+
}
5568
}
5669

5770
return $reflProperty->getValue($object);
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Symfony\Component\Validator\Tests\Fixtures;
4+
5+
class Entity_74_Proxy extends Entity_74
6+
{
7+
public string $notUnset;
8+
9+
public function __construct()
10+
{
11+
unset($this->uninitialized);
12+
}
13+
14+
public function __get($name)
15+
{
16+
return 42;
17+
}
18+
}

‎src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
use Symfony\Component\Validator\Mapping\PropertyMetadata;
1616
use Symfony\Component\Validator\Tests\Fixtures\Entity;
1717
use Symfony\Component\Validator\Tests\Fixtures\Entity_74;
18+
use Symfony\Component\Validator\Tests\Fixtures\Entity_74_Proxy;
1819

1920
class PropertyMetadataTest extends TestCase
2021
{
2122
const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
2223
const CLASSNAME_74 = 'Symfony\Component\Validator\Tests\Fixtures\Entity_74';
24+
const CLASSNAME_74_PROXY = 'Symfony\Component\Validator\Tests\Fixtures\Entity_74_Proxy';
2325
const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent';
2426

2527
public function testInvalidPropertyName()
@@ -66,4 +68,17 @@ public function testGetPropertyValueFromUninitializedProperty()
6668

6769
$this->assertNull($metadata->getPropertyValue($entity));
6870
}
71+
72+
/**
73+
* @requires PHP 7.4
74+
*/
75+
public function testGetPropertyValueFromUninitializedPropertyShouldNotReturnNullIfMagicGetIsPresent()
76+
{
77+
$entity = new Entity_74_Proxy();
78+
$metadata = new PropertyMetadata(self::CLASSNAME_74_PROXY, 'uninitialized');
79+
$notUnsetMetadata = new PropertyMetadata(self::CLASSNAME_74_PROXY, 'notUnset');
80+
81+
$this->assertNull($notUnsetMetadata->getPropertyValue($entity));
82+
$this->assertEquals(42, $metadata->getPropertyValue($entity));
83+
}
6984
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.