From 3647ccaecabbff2eb2bbac1bfb33e27bf330ce90 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 9 Aug 2019 14:35:59 +0200 Subject: [PATCH] [DependencyInjection] improved exception message --- .../Compiler/ResolveClassPass.php | 5 ++++- .../Tests/Compiler/ResolveClassPassTest.php | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php index 5932472ec6..39e9d797f4 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php @@ -29,10 +29,13 @@ class ResolveClassPass implements CompilerPassInterface if ($definition->isSynthetic() || null !== $definition->getClass()) { continue; } - if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $id)) { + if (preg_match('/^\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $id)) { if ($definition instanceof ChildDefinition && !class_exists($id)) { throw new InvalidArgumentException(sprintf('Service definition "%s" has a parent but no class, and its name looks like a FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.', $id)); } + if ('\\' === $id[0]) { + throw new InvalidArgumentException(sprintf('Service definition "%s" has no class, and its name looks like a FQCN but it starts with a backslash; remove the leading backslash.', $id)); + } $definition->setClass($id); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php index 0ab6303164..bcc1d002e8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveClassPassTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\Compiler\ResolveClassPass; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; class ResolveClassPassTest extends TestCase @@ -58,6 +59,17 @@ class ResolveClassPassTest extends TestCase yield ['\DateTime']; } + public function testWontResolveClassFromClassIdWithLeadingBackslash() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Service definition "\App\Some\Service" has no class, and its name looks like a FQCN but it starts with a backslash; remove the leading backslash.'); + + $container = new ContainerBuilder(); + $container->register('\App\Some\Service'); + + (new ResolveClassPass())->process($container); + } + public function testNonFqcnChildDefinition() { $container = new ContainerBuilder();