8000 feature #30116 [Filesystem] Fix mirroring a directory into itself or … · symfony/symfony@e92c120 · GitHub
[go: up one dir, main page]

Skip to content

Commit e92c120

Browse files
committed
feature #30116 [Filesystem] Fix mirroring a directory into itself or in his child with realpath checks (Fleuv, XuruDragon)
This PR was merged into the 4.3-dev branch. Discussion ---------- [Filesystem] Fix mirroring a directory into itself or in his child with realpath checks | Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | none / PR #29857 | License | MIT | Doc PR | n/a This this the continuity of #29857 by @Fleuv Fix a bug while trying to mirror a directory into itself or in a child Adding handle real path checks when mirroring. Commits ------- 8011f49 Handling relative/absolute path 59437a4 Skipping iterations in the mirror() method where the iterated file's path name is equal to the target path
2 parents 67083b6 + 8011f49 commit e92c120

File tree

2 files changed

+34
-51
lines changed

2 files changed

+34
-51
lines changed

src/Symfony/Component/Filesystem/Filesystem.php

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,10 @@ public function mirror($originDir, $targetDir, \Traversable $iterator = null, $o
541541
$originDir = rtrim($originDir, '/\\');
542542
$originDirLen = \strlen($originDir);
543543

544+
if (!$this->exists($originDir)) {
545+
throw new IOException(sprintf('The origin directory specified "%s" was not found.', $originDir), 0, null, $originDir);
546+
}
547+
544548
// Iterate in destination folder to remove obsolete entries
545549
if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) {
546550
$deleteIterator = $iterator;
@@ -564,35 +568,24 @@ public function mirror($originDir, $targetDir, \Traversable $iterator = null, $o
564568
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST);
565569
}
566570

567-
if ($this->exists($originDir)) {
568-
$this->mkdir($targetDir);
569-
}
571+
$this->mkdir($targetDir);
572+
$targetDirInfo = new \SplFileInfo($targetDir);
570573

571574
foreach ($iterator as $file) {
572-
if (false === strpos($file->getPath(), $originDir)) {
573-
throw new IOException(sprintf('Unable to mirror "%s" directory. If the origin directory is relative, try using "realpath" before calling the mirror method.', $originDir), 0, null, $originDir);
575+
if ($file->getPathName() === $targetDir || $file->getRealPath() === $targetDir || 0 === strpos($file->getRealPath(), $targetDirInfo->getRealPath())) {
576+
continue;
574577
}
575578

576579
$target = $targetDir.substr($file->getPathname(), $originDirLen);
577580

578-
if ($copyOnWindows) {
579-
if (is_file($file)) {
580-
$this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
581-
} elseif (is_dir($file)) {
582-
$this->mkdir($target);
583-
} else {
584-
throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
585-
}
581+
if (!$copyOnWindows && is_link($file)) {
582+
$this->symlink($file->getLinkTarget(), $target);
583+
} elseif (is_dir($file)) {
584+
$this->mkdir($target);
585+
} elseif (is_file($file)) {
586+
$this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
586587
} else {
587-
if (is_link($file)) {
588-
$this->symlink($file->getLinkTarget(), $target);
589-
} elseif (is_dir($file)) {
590-
$this->mkdir($target);
591-
} elseif (is_file($file)) {
592-
$this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
593-
} else {
594-
throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
595-
}
588+
throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
596589
}
597590
}
598591
}

src/Symfony/Component/Filesystem/Tests/FilesystemTest.php

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,44 +1332,34 @@ public function testMirrorContentsWithSameNameAsSourceOrTargetWithDeleteOption()
13321332
$this->assertFileNotExists($targetPath.'target');
13331333
}
13341334

1335-
public function testMirrorWithCustomIterator()
1335+
public function testMirrorAvoidCopyingTargetDirectoryIfInSourceDirectory()
13361336
{
13371337
$sourcePath = $this->workspace.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR;
1338-
mkdir($sourcePath);
1339-
1340-
$file = $sourcePath.\DIRECTORY_SEPARATOR.'file';
1341-
file_put_contents($file, 'FILE');
1342-
1343-
$targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'target'.\DIRECTORY_SEPARATOR;
1338+
$directory = $sourcePath.'directory'.\DIRECTORY_SEPARATOR;
1339+
$file1 = $directory.'file1';
1340+
$file2 = $sourcePath.'file2';
13441341

1345-
$splFile = new \SplFileInfo($file);
1346-
$iterator = new \ArrayObject([$splFile]);
1342+
mkdir($sourcePath);
1343+
mkdir($directory);
1344+
file_put_contents($file1, 'FILE1');
1345+
file_put_contents($file2, 'FILE2');
13471346

1348-
$this->filesystem->mirror($sourcePath, $targetPath, $iterator);
1347+
$targetPath = $sourcePath.'target'.\DIRECTORY_SEPARATOR;
13491348

1350-
$this->assertTrue(is_dir($targetPath));
1351-
$this->assertFileEquals($file, $targetPath.\DIRECTORY_SEPARATOR.'file');
1352-
}
1353-
1354-
/**
1355-
* @expectedException \Symfony\Component\Filesystem\Exception\IOException
1356-
* @expectedExceptionMessageRegExp /Unable to mirror "(.*)" directory/
1357-
*/
1358-
public function testMirrorWithCustomIteratorWithRelativePath()
1359-
{
1360-
$sourcePath = $this->workspace.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR;
1361-
$realSourcePath = $this->workspace.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR;
1362-
mkdir($realSourcePath);
1349+
if ('\\' !== \DIRECTORY_SEPARATOR) {
1350+
$this->filesystem->symlink($targetPath, $sourcePath.'target_simlink');
1351+
}
13631352

1364-
$file = $realSourcePath.'file';
1365-
file_put_contents($file, 'FILE');
1353+
$this->filesystem->mirror($sourcePath, $targetPath, null, ['delete' => true]);
13661354

1367-
$targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'target'.\DIRECTORY_SEPARATOR.'..'.\DIRECTORY_SEPARATOR.'target'.\DIRECTORY_SEPARATOR;
1355+
$this->assertTrue($this->filesystem->exists($targetPath));
1356+
$this->assertTrue($this->filesystem->exists($targetPath.'directory'));
13681357

1369-
$splFile = new \SplFileInfo($file);
1370-
$iterator = new \ArrayObject([$splFile]);
1358+
$this->assertFileEquals($file1, $targetPath.'directory'.\DIRECTORY_SEPARATOR.'file1');
1359+
$this->assertFileEquals($file2, $targetPath.'file2');
13711360

1372-
$this->filesystem->mirror($sourcePath, $targetPath, $iterator);
1361+
$this->assertFalse($this->filesystem->exists($targetPath.'target_simlink'));
1362+
$this->assertFalse($this->filesystem->exists($targetPath.'target'));
13731363
}
13741364

13751365
/**

0 commit comments

Comments
 (0)
0