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 5cd10b0

Browse filesBrowse files
filiplikavcannicolas-grekas
authored andcommitted
[PropertyAccess] Fix handling of uninitialized property of parent class
1 parent 9f5238d commit 5cd10b0
Copy full SHA for 5cd10b0

File tree

Expand file treeCollapse file tree

4 files changed

+54
-3
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+54
-3
lines changed

‎src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyAccess/PropertyAccessor.php
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid
401401
&& $object instanceof $trace['class']
402402
&& preg_match('/Return value (?:of .*::\w+\(\) )?must be of (?:the )?type (\w+), null returned$/', $e->getMessage(), $matches)
403403
) {
404-
throw new AccessException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', !str_contains(\get_class($object), "@anonymous\0") ? \get_class($object) : (get_parent_class($object) ?: 'class').'@anonymous', $access[self::ACCESS_NAME], $matches[1]), 0, $e);
404+
throw new AccessException(sprintf('The method "%s::%s()" returned "null", but expected type "%3$s". Did you forget to initialize a property or to make the return type nullable using "?%3$s"?', get_debug_type($object), $access[self::ACCESS_NAME], $matches[1]), 0, $e);
405405
}
406406

407407
throw $e;
@@ -436,8 +436,8 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid
436436
}
437437
} catch (\Error $e) {
438438
// handle uninitialized properties in PHP >= 7.4
439-
if (\PHP_VERSION_ID >= 70400 && preg_match('/^Typed property ('.preg_quote(get_debug_type($object), '/').')::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) {
440-
$r = new \ReflectionProperty($class, $matches[2]);
439+
if (\PHP_VERSION_ID >= 70400 && preg_match('/^Typed property ([\w\\\\@]+)::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) {
440+
$r = new \ReflectionProperty(str_contains($matches[1], '@anonymous') ? $class : $matches[1], $matches[2]);
441441
$type = ($type = $r->getType()) instanceof \ReflectionNamedType ? $type->getName() : (string) $type;
442442

443443
throw new AccessException(sprintf('The property "%s::$%s" is not readable because it is typed "%s". You should initialize it or declare a default value instead.', $matches[1], $r->getName(), $type), 0, $e);
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\PropertyAccess\Tests\Fixtures;
13+
14+
class ExtendedUninitializedProperty extends UninitializedProperty
15+
{
16+
17+
}

‎src/Symfony/Component/PropertyAccess/Tests/Fixtures/UninitializedProperty.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyAccess/Tests/Fixtures/UninitializedProperty.php
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,15 @@
1414
class UninitializedProperty
1515
{
1616
public string $uninitialized;
17+
private string $privateUninitialized;
18+
19+
public function getPrivateUninitialized(): string
20+
{
21+
return $this->privateUninitialized;
22+
}
23+
24+
public function setPrivateUninitialized(string $privateUninitialized): void
25+
{
26+
$this->privateUninitialized = $privateUninitialized;
27+
}
1728
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\PropertyAccess\Exception\UnexpectedTypeException;
2121
use Symfony\Component\PropertyAccess\PropertyAccess;
2222
use Symfony\Component\PropertyAccess\PropertyAccessor;
23+
use Symfony\Component\PropertyAccess\Tests\Fixtures\ExtendedUninitializedProperty;
2324
use Symfony\Component\PropertyAccess\Tests\Fixtures\ReturnTyped;
2425
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestAdderRemoverInvalidArgumentLength;
2526
use Symfony\Component\PropertyAccess\Tests\Fixtures\TestAdderRemoverInvalidMethods;
@@ -211,6 +212,28 @@ public function testGetValueThrowsExceptionIfUninitializedPropertyOfAnonymousCla
211212
$this->propertyAccessor->getValue($object, 'uninitialized');
212213
}
213214

215+
/**
216+
* @requires PHP 7.4
217+
*/
218+
public function testGetValueThrowsExceptionIfUninitializedNotNullableOfParentClass()
219+
{
220+
$this->expectException(AccessException::class);
221+
$this->expectExceptionMessage('The property "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedProperty::$uninitialized" is not readable because it is typed "string". You should initialize it or declare a default value instead.');
222+
223+
$this->propertyAccessor->getValue(new ExtendedUninitializedProperty(), 'uninitialized');
224+
}
225+
226+
/**
227+
* @requires PHP 7.4
228+
*/
229+
public function testGetValueThrowsExceptionIfUninitializedNotNullablePropertyWithGetterOfParentClass()
230+
{
231+
$this->expectException(AccessException::class);
232+
$this->expectExceptionMessage('The property "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedProperty::$privateUninitialized" is not readable because it is typed "string". You should initialize it or declare a default value instead.');
233+
234+
$this->propertyAccessor->getValue(new ExtendedUninitializedProperty(), 'privateUninitialized');
235+
}
236+
214237
public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetterOfAnonymousStdClass()
215238
{
216239
$this->expectException(AccessException::class);

0 commit comments

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