8000 feature #26771 [Filesystem] Fix mirroring a directory with a relative… · symfony/symfony@6fbb494 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6fbb494

Browse files
committed
feature #26771 [Filesystem] Fix mirroring a directory with a relative path and a custom iterator (fxbt)
This PR was submitted for the 2.8 branch but it was squashed and merged into the 4.2-dev branch instead (closes #26771). Discussion ---------- [Filesystem] Fix mirroring a directory with a relative path and a custom iterator | Q | A | ------------- | --- | Branch? | 2.8 up to 4.1 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | The Filesystem::mirror method with a Finder iterator doesn't work if the origin directory is relative. This is a case where it won't work: ``` $dir = '/data/../data/'; $finder = (new Finder())->in($dir)->getIterator(); (new Filesystem())->mirror($dir, '/tmp', $finder); ``` The finder will return file objects like this : ``` SplFileInfo { pathname: "/data/file.tmp" ... } ``` But the following line will fail because because the `$file->getPathname()` and the `$originDir` are differents. ``` $target = $targetDir.substr($file->getPathname(), $originDirLen); // $file->getPathname() = '/data/file.tmp' // $originDirLen = strlen('/data/../data/') = 14 // $target = '/tmp' instead of '/tpm/file.tpm' ``` In some case, it's even worse. If the filename length is bigger than the `$originDirLen`, the target file will be a file with a completely wrong name: ``` // $file->getPathname() = '/data/file123456789.tmp' // $originDirLen = strlen('/data/../data/') = 14 // $target = '/tmp/56789.tmp' instead of '/tpm/file123456789.tmp' ``` I fixed this on my side by using the realpath function everytime i'm calling the mirror method, but i doubt this is the desired behavior. Commits ------- 27b673c [Filesystem] Fix mirroring a directory with a relative path and a custom iterator
2 parents c01359e + 27b673c commit 6fbb494

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

src/Symfony/Component/Filesystem/Filesystem.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,10 @@ public function mirror($originDir, $targetDir, \Traversable $iterator = null, $o
572572
}
573573

574574
foreach ($iterator as $file) {
575+
if (false === strpos($file->getPath(), $originDir)) {
576+
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);
577+
}
578+
575579
$target = $targetDir.substr($file->getPathname(), $originDirLen);
576580

577581
if ($copyOnWindows) {

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

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

1335+
public function testMirrorWithCustomIterator()
1336+
{
1337+
$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;
1344+
1345+
$splFile = new \SplFileInfo($file);
1346+
$iterator = new \ArrayObject(array($splFile));
1347+
1348+
$this->filesystem->mirror($sourcePath, $targetPath, $iterator);
1349+
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);
1363+
1364+
$file = $realSourcePath.'file';
1365+
file_put_contents($file, 'FILE');
1366+
1367+
$targetPath = $this->workspace.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'target'.DIRECTORY_SEPARATOR;
1368+
1369+
$splFile = new \SplFileInfo($file);
1370+
$iterator = new \ArrayObject(array($splFile));
1371+
1372+
$this->filesystem->mirror($sourcePath, $targetPath, $iterator);
1373+
}
1374+
13351375
/**
13361376
* @dataProvider providePathsForIsAbsolutePath
13371377
*/

0 commit comments

Comments
 (0)
0