From dc50aa3b55b5504f55a8faf8ccd115561cb14315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 23 Apr 2021 00:49:37 +0200 Subject: [PATCH] [Config][DependencyInjection] Uniformize trailing slash handling --- .../Component/Config/Loader/FileLoader.php | 4 +-- .../Fixtures/ExcludeTrailingSlash/bar.txt | 0 .../ExcludeTrailingSlash/exclude/baz.txt | 0 .../Fixtures/ExcludeTrailingSlash/foo.txt | 0 .../Config/Tests/Loader/FileLoaderTest.php | 22 ++++++++++++++ .../Tests/Resource/GlobResourceTest.php | 1 + .../DependencyInjection/Loader/FileLoader.php | 4 +-- .../Tests/Loader/FileLoaderTest.php | 29 +++++++++++++++++++ 8 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Component/Config/Tests/Fixtures/ExcludeTrailingSlash/bar.txt create mode 100644 src/Symfony/Component/Config/Tests/Fixtures/ExcludeTrailingSlash/exclude/baz.txt create mode 100644 src/Symfony/Component/Config/Tests/Fixtures/ExcludeTrailingSlash/foo.txt diff --git a/src/Symfony/Component/Config/Loader/FileLoader.php b/src/Symfony/Component/Config/Loader/FileLoader.php index b7c2491b5b..5ead5961f6 100644 --- a/src/Symfony/Component/Config/Loader/FileLoader.php +++ b/src/Symfony/Component/Config/Loader/FileLoader.php @@ -82,8 +82,8 @@ abstract class FileLoader extends Loader $excluded = []; foreach ((array) $exclude as $pattern) { foreach ($this->glob($pattern, true, $_, false, true) as $path => $info) { - // normalize Windows slashes - $excluded[str_replace('\\', '/', $path)] = true; + // normalize Windows slashes and remove trailing slashes + $excluded[rtrim(str_replace('\\', '/', $path), '/')] = true; } } diff --git a/src/Symfony/Component/Config/Tests/Fixtures/ExcludeTrailingSlash/bar.txt b/src/Symfony/Component/Config/Tests/Fixtures/ExcludeTrailingSlash/bar.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Symfony/Component/Config/Tests/Fixtures/ExcludeTrailingSlash/exclude/baz.txt b/src/Symfony/Component/Config/Tests/Fixtures/ExcludeTrailingSlash/exclude/baz.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Symfony/Component/Config/Tests/Fixtures/ExcludeTrailingSlash/foo.txt b/src/Symfony/Component/Config/Tests/Fixtures/ExcludeTrailingSlash/foo.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php b/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php index 5fc8ce0a82..023bbe0f31 100644 --- a/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php +++ b/src/Symfony/Component/Config/Tests/Loader/FileLoaderTest.php @@ -127,6 +127,28 @@ class FileLoaderTest extends TestCase $this->assertCount(2, $loadedFiles); $this->assertNotContains('ExcludeFile.txt', $loadedFiles); } + + /** + * @dataProvider excludeTrailingSlashConsistencyProvider + */ + public function testExcludeTrailingSlashConsistency(string $exclude) + { + $loader = new TestFileLoader(new FileLocator(__DIR__.'/../Fixtures')); + $loadedFiles = $loader->import('ExcludeTrailingSlash/*', null, false, null, $exclude); + $this->assertCount(2, $loadedFiles); + $this->assertNotContains('baz.txt', $loadedFiles); + } + + public function excludeTrailingSlashConsistencyProvider(): iterable + { + yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo/']; + yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo']; + yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo/*']; + yield [__DIR__.'/../Fixtures/*/ExcludeToo']; + yield [__DIR__.'/../Fixtures/*/ExcludeToo/']; + yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo/*']; + yield [__DIR__.'/../Fixtures/Exclude/ExcludeToo/AnotheExcludedFile.txt']; + } } class TestFileLoader extends FileLoader diff --git a/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php index 7958332cb0..fd317eb55c 100644 --- a/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/GlobResourceTest.php @@ -177,6 +177,7 @@ class GlobResourceTest extends TestCase $expected = [ $dir.'/Exclude/ExcludeToo/AnotheExcludedFile.txt', + $dir.'/ExcludeTrailingSlash/exclude/baz.txt', $dir.'/foo.xml', ]; diff --git a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php index 4b8a5f48c7..e01db7eea6 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php @@ -166,8 +166,8 @@ abstract class FileLoader extends BaseFileLoader $excludePrefix = $resource->getPrefix(); } - // normalize Windows slashes - $excludePaths[str_replace('\\', '/', $path)] = true; + // normalize Windows slashes and remove trailing slashes + $excludePaths[rtrim(str_replace('\\', '/', $path), '/')] = true; } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php index 8362402ce9..794753da21 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php @@ -239,6 +239,35 @@ class FileLoaderTest extends TestCase 'yaml/*' ); } + + /** + * @dataProvider excludeTrailingSlashConsistencyProvider + */ + public function testExcludeTrailingSlashConsistency(string $exclude) + { + $container = new ContainerBuilder(); + $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures')); + $loader->registerClasses( + new Definition(), + 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\', + 'Prototype/*', + $exclude + ); + + $this->assertTrue($container->has(Foo::class)); + $this->assertFalse($container->has(DeeperBaz::class)); + } + + public function excludeTrailingSlashConsistencyProvider(): iterable + { + yield ['Prototype/OtherDir/AnotherSub/']; + yield ['Prototype/OtherDir/AnotherSub']; + yield ['Prototype/OtherDir/AnotherSub/*']; + yield ['Prototype/*/AnotherSub']; + yield ['Prototype/*/AnotherSub/']; + yield ['Prototype/*/AnotherSub/*']; + yield ['Prototype/OtherDir/AnotherSub/DeeperBaz.php']; + } } class TestFileLoader extends FileLoader