From 3d807c1dc2cd3d36d18a548f41d062c036f1b3d1 Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Thu, 12 Dec 2024 00:04:05 +0100 Subject: [PATCH] [Routing] Validate "namespace" (when using `Psr4DirectoryLoader`) --- .../Routing/Loader/Psr4DirectoryLoader.php | 5 ++++ .../Tests/Loader/Psr4DirectoryLoaderTest.php | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/Symfony/Component/Routing/Loader/Psr4DirectoryLoader.php b/src/Symfony/Component/Routing/Loader/Psr4DirectoryLoader.php index 738b56f499cf8..fb48da15d8515 100644 --- a/src/Symfony/Component/Routing/Loader/Psr4DirectoryLoader.php +++ b/src/Symfony/Component/Routing/Loader/Psr4DirectoryLoader.php @@ -15,6 +15,7 @@ use Symfony\Component\Config\Loader\DirectoryAwareLoaderInterface; use Symfony\Component\Config\Loader\Loader; use Symfony\Component\Config\Resource\DirectoryResource; +use Symfony\Component\Routing\Exception\InvalidArgumentException; use Symfony\Component\Routing\RouteCollection; /** @@ -43,6 +44,10 @@ public function load(mixed $resource, ?string $type = null): ?RouteCollection return new RouteCollection(); } + if (!preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+\\\)++$/', trim($resource['namespace'], '\\').'\\')) { + throw new InvalidArgumentException(\sprintf('Namespace "%s" is not a valid PSR-4 prefix.', $resource['namespace'])); + } + return $this->loadFromDirectory($path, trim($resource['namespace'], '\\')); } diff --git a/src/Symfony/Component/Routing/Tests/Loader/Psr4DirectoryLoaderTest.php b/src/Symfony/Component/Routing/Tests/Loader/Psr4DirectoryLoaderTest.php index 81515b862d735..330bc145e4a4b 100644 --- a/src/Symfony/Component/Routing/Tests/Loader/Psr4DirectoryLoaderTest.php +++ b/src/Symfony/Component/Routing/Tests/Loader/Psr4DirectoryLoaderTest.php @@ -15,6 +15,7 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Loader\DelegatingLoader; use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Routing\Exception\InvalidArgumentException; use Symfony\Component\Routing\Loader\AttributeClassLoader; use Symfony\Component\Routing\Loader\Psr4DirectoryLoader; use Symfony\Component\Routing\Route; @@ -90,6 +91,34 @@ public static function provideNamespacesThatNeedTrimming(): array ]; } + /** + * @dataProvider provideInvalidPsr4Namespaces + */ + public function testInvalidPsr4Namespace(string $namespace, string $expectedExceptionMessage) + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage($expectedExceptionMessage); + + $this->getLoader()->load( + ['path' => 'Psr4Controllers', 'namespace' => $namespace], + 'attribute' + ); + } + + public static function provideInvalidPsr4Namespaces(): array + { + return [ + 'slash instead of back-slash' => [ + 'namespace' => 'App\Application/Controllers', + 'exceptionMessage' => 'Namespace "App\Application/Controllers" is not a valid PSR-4 prefix.', + ], + 'invalid namespace' => [ + 'namespace' => 'App\Contro llers', + 'exceptionMessage' => 'Namespace "App\Contro llers" is not a valid PSR-4 prefix.', + ], + ]; + } + private function loadPsr4Controllers(): RouteCollection { return $this->getLoader()->load(