8000 bug #30313 Avoid mutating the Finder when building the iterator (stof) · symfony/symfony@47d26f6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 47d26f6

Browse files
committed
bug #30313 Avoid mutating the Finder when building the iterator (stof)
This PR was merged into the 3.4 branch. Discussion ---------- Avoid mutating the Finder when building the iterator | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a When excluding dot files or vcs files (which is done by default), the Finder object was mutated each time `searchInDirectory` was called to register the extra exclusions. This leads to registering them multiple times when the method is called multiple times (which happens either because you have multiple directories in `->in()` or because you call `getIterator` multiple times, for instance because of using `hasResults` or `count`). This mutation create bugs if the Finder object is reconfigured between the 2 calls to `getIterator` to disable some of these ignore rules, as they would already be registered in the other config properties. New tests have been added to reproduce these bugs and prevent regressions. This mutation is now avoided by using a local array for the final configuration, preserving the user configuration. Commits ------- 94989fe Avoid mutating the Finder when building the iterator
2 parents df0fc5e + 94989fe commit 47d26f6

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

src/Symfony/Component/Finder/Finder.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -645,12 +645,15 @@ public function count()
645645
*/
646646
private function searchInDirectory($dir)
647647
{
648+
$exclude = $this->exclude;
649+
$notPaths = $this->notPaths;
650+
648651
if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
649-
$this->exclude = array_merge($this->exclude, self::$vcsPatterns);
652+
$exclude = array_merge($exclude, self::$vcsPatterns);
650653
}
651654

652655
if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) {
653-
$this->notPaths[] = '#(^|/)\..+(/|$)#';
656+
$notPaths[] = '#(^|/)\..+(/|$)#';
654657
}
655658

656659
$minDepth = 0;
@@ -683,8 +686,8 @@ private function searchInDirectory($dir)
683686

684687
$iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);
685688

686-
if ($this->exclude) {
687-
$iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
689+
if ($exclude) {
690+
$iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $exclude);
688691
}
689692

690693
$iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
@@ -717,8 +720,8 @@ private function searchInDirectory($dir)
717720
$iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
718721
}
719722

720-
if ($this->paths || $this->notPaths) {
721-
$iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
723+
if ($this->paths || $notPaths) {
724+
$iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $notPaths);
722725
}
723726

724727
if ($this->sort) {

src/Symfony/Component/Finder/Tests/FinderTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,18 @@ public function testIgnoreVCS()
199199
$this->assertIterator($this->toAbsolute(['foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar']), $finder->in(self::$tmpDir)->getIterator());
200200
}
201201

202+
public function testIgnoreVCSCanBeDisabledAfterFirstIteration()
203+
{
204+
$finder = $this->buildFinder();
205+
$finder->in(self::$tmpDir);
206+
$finder->ignoreDotFiles(false);
207+
208+
$this->assertIterator($this->toAbsolute(['foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar']), $finder->getIterator());
209+
210+
$finder->ignoreVCS(false);
211+
$this->assertIterator($this->toAbsolute(['.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'toto/.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar']), $finder->getIterator());
212+
}
213+
202214
public function testIgnoreDotFiles()
203215
{
204216
$finder = $this->buildFinder();
@@ -214,6 +226,17 @@ public function testIgnoreDotFiles()
214226
$this->assertIterator($this->toAbsolute(['foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar']), $finder->in(self::$tmpDir)->getIterator());
215227
}
216228

229+
public function testIgnoreDotFilesCanBeDisabledAfterFirstIteration()
230+
{
231+
$finder = $this->buildFinder();
232+
$finder->in(self::$tmpDir);
233+
234+
$this->assertIterator($this->toAbsolute(['foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar']), $finder->getIterator());
235+
236+
$finder->ignoreDotFiles(false);
237+
$this->assertIterator($this->toAbsolute(['foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar']), $finder->getIterator());
238+
}
239+
217240
public function testSortByName()
218241
{
219242
$finder = $this->buildFinder();

0 commit comments

Comments
 (0)
0