From 80abe434f1462ef0cf461a641e0bdf0f11cd7c11 Mon Sep 17 00:00:00 2001 From: Samuel ROZE Date: Sun, 2 Apr 2017 11:10:36 +0100 Subject: [PATCH 1/3] [Finder] Wildcard while using double-star without leading slash --- src/Symfony/Component/Finder/Glob.php | 12 +++++++++--- src/Symfony/Component/Finder/Tests/GlobTest.php | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Finder/Glob.php b/src/Symfony/Component/Finder/Glob.php index 1fd508f2581f8..f82a54f70a097 100644 --- a/src/Symfony/Component/Finder/Glob.php +++ b/src/Symfony/Component/Finder/Glob.php @@ -60,9 +60,15 @@ public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardS $firstByte = '/' === $car; - if ($firstByte && $strictWildcardSlash && isset($glob[$i + 3]) && '**/' === $glob[$i + 1].$glob[$i + 2].$glob[$i + 3]) { - $car = $strictLeadingDot ? '/(?:(?=[^\.])[^/]++/)*' : '/(?:[^/]++/)*'; - $i += 3; + if ($firstByte && $strictWildcardSlash) { + if (isset($glob[$i + 3]) && '**/' === $glob[$i + 1].$glob[$i + 2].$glob[$i + 3]) { + $car = $strictLeadingDot ? '/(?:(?=[^\.])[^/]++/)*' : '/(?:[^/]++/)*'; + $i += 3; + } elseif (isset($glob[$i + 2]) && '**' === $glob[$i + 1].$glob[$i + 2]) { + $car = '/.*'; + $i += 2; + } + if ('/' === $delimiter) { $car = str_replace('/', '\\/', $car); } diff --git a/src/Symfony/Component/Finder/Tests/GlobTest.php b/src/Symfony/Component/Finder/Tests/GlobTest.php index e9928a9a68737..ab67fc7338d41 100755 --- a/src/Symfony/Component/Finder/Tests/GlobTest.php +++ b/src/Symfony/Component/Finder/Tests/GlobTest.php @@ -58,4 +58,21 @@ public function testGlobToRegexDoubleStarNonStrictDots() $this->assertSame(array('.dot/b/c.neon', '.dot/b/d.neon', 'one/b/c.neon', 'one/b/d.neon'), $match); } + + public function testGlobToRegexDoubleStarWithoutLeadingSlash() + { + $finder = new Finder(); + $finder->ignoreDotFiles(false); + $regex = Glob::toRegex('/Fixtures/one/**'); + + foreach ($finder->in(__DIR__) as $k => $v) { + $k = str_replace(DIRECTORY_SEPARATOR, '/', $k); + if (preg_match($regex, substr($k, strlen(__DIR__)))) { + $match[] = substr($k, 10 + strlen(__DIR__)); + } + } + sort($match); + + $this->assertSame(array('one/a', 'one/b', 'one/b/c.neon', 'one/b/d.neon'), $match); + } } From 94fe26a4e4c21f6cf987003f51d0f7347a2e2827 Mon Sep 17 00:00:00 2001 From: Samuel ROZE Date: Wed, 5 Apr 2017 17:14:28 +0100 Subject: [PATCH 2/3] Accounting for strict leading dots --- src/Symfony/Component/Finder/Glob.php | 2 +- .../Component/Finder/Tests/Fixtures/one/.dot | 1 + src/Symfony/Component/Finder/Tests/GlobTest.php | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Finder/Tests/Fixtures/one/.dot diff --git a/src/Symfony/Component/Finder/Glob.php b/src/Symfony/Component/Finder/Glob.php index f82a54f70a097..1d800ba93e1d0 100644 --- a/src/Symfony/Component/Finder/Glob.php +++ b/src/Symfony/Component/Finder/Glob.php @@ -65,7 +65,7 @@ public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardS $car = $strictLeadingDot ? '/(?:(?=[^\.])[^/]++/)*' : '/(?:[^/]++/)*'; $i += 3; } elseif (isset($glob[$i + 2]) && '**' === $glob[$i + 1].$glob[$i + 2]) { - $car = '/.*'; + $car = $strictLeadingDot ? '/(?=[^\.]).*' : '/.*'; $i += 2; } diff --git a/src/Symfony/Component/Finder/Tests/Fixtures/one/.dot b/src/Symfony/Component/Finder/Tests/Fixtures/one/.dot new file mode 100644 index 0000000000000..1028065f8a337 --- /dev/null +++ b/src/Symfony/Component/Finder/Tests/Fixtures/one/.dot @@ -0,0 +1 @@ +.dot \ No newline at end of file diff --git a/src/Symfony/Component/Finder/Tests/GlobTest.php b/src/Symfony/Component/Finder/Tests/GlobTest.php index ab67fc7338d41..d48ac1fc5452b 100755 --- a/src/Symfony/Component/Finder/Tests/GlobTest.php +++ b/src/Symfony/Component/Finder/Tests/GlobTest.php @@ -75,4 +75,21 @@ public function testGlobToRegexDoubleStarWithoutLeadingSlash() $this->assertSame(array('one/a', 'one/b', 'one/b/c.neon', 'one/b/d.neon'), $match); } + + public function testGlobToRegexDoubleStarWithoutLeadingSlashNotStrictLeadingDot() + { + $finder = new Finder(); + $finder->ignoreDotFiles(false); + $regex = Glob::toRegex('/Fixtures/one/**', false); + + foreach ($finder->in(__DIR__) as $k => $v) { + $k = str_replace(DIRECTORY_SEPARATOR, '/', $k); + if (preg_match($regex, substr($k, strlen(__DIR__)))) { + $match[] = substr($k, 10 + strlen(__DIR__)); + } + } + sort($match); + + $this->assertSame(array('one/.dot', 'one/a', 'one/b', 'one/b/c.neon', 'one/b/d.neon'), $match); + } } From 2c3ef4253aef7dabd89c30ab6a7425d5d37b1e12 Mon Sep 17 00:00:00 2001 From: Samuel ROZE Date: Thu, 6 Apr 2017 10:24:04 +0100 Subject: [PATCH 3/3] Refactored in order to use only one if and construct the regex --- src/Symfony/Component/Finder/Glob.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Finder/Glob.php b/src/Symfony/Component/Finder/Glob.php index 1d800ba93e1d0..df8b86fa5f1a6 100644 --- a/src/Symfony/Component/Finder/Glob.php +++ b/src/Symfony/Component/Finder/Glob.php @@ -60,15 +60,19 @@ public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardS $firstByte = '/' === $car; - if ($firstByte && $strictWildcardSlash) { - if (isset($glob[$i + 3]) && '**/' === $glob[$i + 1].$glob[$i + 2].$glob[$i + 3]) { - $car = $strictLeadingDot ? '/(?:(?=[^\.])[^/]++/)*' : '/(?:[^/]++/)*'; - $i += 3; - } elseif (isset($glob[$i + 2]) && '**' === $glob[$i + 1].$glob[$i + 2]) { - $car = $strictLeadingDot ? '/(?=[^\.]).*' : '/.*'; - $i += 2; + if ($firstByte && $strictWildcardSlash && isset($glob[$i + 2]) && '**' === $glob[$i + 1].$glob[$i + 2] && (!isset($glob[$i + 3]) || '/' === $glob[$i + 3])) { + $car = '[^/]++/'; + if (!isset($glob[$i + 3])) { + $car .= '?'; } + if ($strictLeadingDot) { + $car = '(?=[^\.])'.$car; + } + + $car = '/(?:'.$car.')*'; + $i += 2 + isset($glob[$i + 3]); + if ('/' === $delimiter) { $car = str_replace('/', '\\/', $car); }