Skip to content

Commit

Permalink
Merge branch '5.3' into 5.4
Browse files Browse the repository at this point in the history
* 5.3:
  [HttpClient] Remove deprecated usage of `GuzzleHttp\Promise\queue`
  [PropertyAccess] Fix handling of uninitialized property of anonymous class
  [FrameworkBundle] Allow default cache pools to be overwritten by user
  [DependencyInjection] fix test
  ResolveBindingsPass remove loading of class iterable
  [FrameworkBundle] Avoid calling rtrim(null, '/') in AssetsInstallCommand
  [DependencyInjection] Fix nested env var with resolve processor
  Allow OutputFormatter::escape() to be used for escaping URLs used in <href>
  allow a zero time-limit
  [DependencyInjection] Ignore argument type check in CheckTypeDeclarationsPass if it's a Definition with a factory
  [Validators] Add translations for Slovak #43735
  • Loading branch information
nicolas-grekas committed Jan 12, 2022
2 parents 0e0693c + 3272353 commit 4bb27fa
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
6 changes: 3 additions & 3 deletions PropertyAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -482,11 +482,11 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid
}
} catch (\Error $e) {
// handle uninitialized properties in PHP >= 7.4
if (\PHP_VERSION_ID >= 70400 && preg_match('/^Typed property ([\w\\\]+)::\$(\w+) must not be accessed before initialization$/', $e->getMessage(), $matches)) {
$r = new \ReflectionProperty($matches[1], $matches[2]);
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)) {
$r = new \ReflectionProperty($class, $matches[2]);
$type = ($type = $r->getType()) instanceof \ReflectionNamedType ? $type->getName() : (string) $type;

throw new UninitializedPropertyException(sprintf('The property "%s::$%s" is not readable because it is typed "%s". You should initialize it or declare a default value instead.', $r->getDeclaringClass()->getName(), $r->getName(), $type), 0, $e);
throw new UninitializedPropertyException(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);
}

throw $e;
Expand Down
42 changes: 38 additions & 4 deletions Tests/PropertyAccessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\PropertyAccess\Exception\AccessException;
use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException;
use Symfony\Component\PropertyAccess\Exception\NoSuchIndexException;
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
Expand Down Expand Up @@ -191,7 +190,7 @@ public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetter()

public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetterOfAnonymousClass()
{
$this->expectException(AccessException::class);
$this->expectException(UninitializedPropertyException::class);
$this->expectExceptionMessage('The method "class@anonymous::getUninitialized()" returned "null", but expected type "array". Did you forget to initialize a property or to make the return type nullable using "?array"?');

$object = eval('return new class() {
Expand All @@ -206,9 +205,44 @@ public function getUninitialized(): array
$this->propertyAccessor->getValue($object, 'uninitialized');
}

/**
* @requires PHP 7.4
*/
public function testGetValueThrowsExceptionIfUninitializedNotNullablePropertyWithGetterOfAnonymousClass()
{
$this->expectException(UninitializedPropertyException::class);
$this->expectExceptionMessage('The property "class@anonymous::$uninitialized" is not readable because it is typed "string". You should initialize it or declare a default value instead.');

$object = eval('return new class() {
private string $uninitialized;
public function getUninitialized(): string
{
return $this->uninitialized;
}
};');

$this->propertyAccessor->getValue($object, 'uninitialized');
}

/**
* @requires PHP 7.4
*/
public function testGetValueThrowsExceptionIfUninitializedPropertyOfAnonymousClass()
{
$this->expectException(UninitializedPropertyException::class);
$this->expectExceptionMessage('The property "class@anonymous::$uninitialized" is not readable because it is typed "string". You should initialize it or declare a default value instead.');

$object = eval('return new class() {
public string $uninitialized;
};');

$this->propertyAccessor->getValue($object, 'uninitialized');
}

public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetterOfAnonymousStdClass()
{
$this->expectException(AccessException::class);
$this->expectException(UninitializedPropertyException::class);
$this->expectExceptionMessage('The method "stdClass@anonymous::getUninitialized()" returned "null", but expected type "array". Did you forget to initialize a property or to make the return type nullable using "?array"?');

$object = eval('return new class() extends \stdClass {
Expand All @@ -225,7 +259,7 @@ public function getUninitialized(): array

public function testGetValueThrowsExceptionIfUninitializedPropertyWithGetterOfAnonymousChildClass()
{
$this->expectException(AccessException::class);
$this->expectException(UninitializedPropertyException::class);
$this->expectExceptionMessage('The method "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedPrivateProperty@anonymous::getUninitialized()" returned "null", but expected type "array". Did you forget to initialize a property or to make the return type nullable using "?array"?');

$object = eval('return new class() extends \Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedPrivateProperty {};');
Expand Down

0 comments on commit 4bb27fa

Please sign in to comment.