Skip to content

Commit

Permalink
[Filesystem] Follow symlinks when dumping files
Browse files Browse the repository at this point in the history
  • Loading branch information
ausi authored and nicolas-grekas committed May 30, 2023
1 parent b2f79d8 commit 38d3a96
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 2 deletions.
6 changes: 6 additions & 0 deletions Filesystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,12 @@ public function dumpFile(string $filename, $content)

$dir = \dirname($filename);

if (is_link($filename) && $linkTarget = $this->readlink($filename)) {
$this->dumpFile(Path::makeAbsolute($linkTarget, $dir), $content);

return;
}

if (!is_dir($dir)) {
$this->mkdir($dir);
}
Expand Down
67 changes: 65 additions & 2 deletions Tests/FilesystemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1091,14 +1091,16 @@ public function testReadBrokenLink()
{
$this->markAsSkippedIfSymlinkIsMissing();

if ('\\' === \DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Windows does not support creating "broken" symlinks');
if ('\\' === \DIRECTORY_SEPARATOR && \PHP_VERSION_ID < 70400) {
$this->markTestSkipped('Windows does not support reading "broken" symlinks in PHP < 7.4.0');
}

$file = $this->workspace.'/file';
$link = $this->workspace.'/link';

touch($file);
$this->filesystem->symlink($file, $link);
$this->filesystem->remove($file);

$this->assertEquals($file, $this->filesystem->readlink($link));
$this->assertNull($this->filesystem->readlink($link, true));
Expand Down Expand Up @@ -1605,6 +1607,38 @@ public function testDumpFileOverwritesAnExistingFile()
$this->assertStringEqualsFile($filename, 'bar');
}

public function testDumpFileFollowsSymlink()
{
$filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo.txt';
file_put_contents($filename, 'FOO BAR');
$linknameA = $this->workspace.\DIRECTORY_SEPARATOR.'bar.txt';
$linknameB = $this->workspace.\DIRECTORY_SEPARATOR.'baz.txt';
$this->filesystem->symlink($filename, $linknameA);
$this->filesystem->symlink($linknameA, $linknameB);

$this->filesystem->dumpFile($linknameB, 'bar');

$this->assertFileExists($filename);
$this->assertFileExists($linknameA);
$this->assertFileExists($linknameB);
$this->assertStringEqualsFile($filename, 'bar');
$this->assertStringEqualsFile($linknameA, 'bar');
$this->assertStringEqualsFile($linknameB, 'bar');

// Windows does not support reading "broken" symlinks in PHP < 7.4.0
if ('\\' === \DIRECTORY_SEPARATOR && \PHP_VERSION_ID < 70400) {
return;
}

$this->filesystem->remove($filename);
$this->filesystem->dumpFile($linknameB, 'baz');

$this->assertFileExists($filename);
$this->assertStringEqualsFile($filename, 'baz');
$this->assertStringEqualsFile($linknameA, 'baz');
$this->assertStringEqualsFile($linknameB, 'baz');
}

public function testDumpFileWithFileScheme()
{
$scheme = 'file://';
Expand Down Expand Up @@ -1678,6 +1712,35 @@ public function testAppendToFileWithResource()
}
}

public function testAppendToFileFollowsSymlink()
{
$filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo.txt';
file_put_contents($filename, 'foo');
$linknameA = $this->workspace.\DIRECTORY_SEPARATOR.'bar.txt';
$linknameB = $this->workspace.\DIRECTORY_SEPARATOR.'baz.txt';
$this->filesystem->symlink($filename, $linknameA);
$this->filesystem->symlink($linknameA, $linknameB);

$this->filesystem->appendToFile($linknameA, 'bar');
$this->filesystem->appendToFile($linknameB, 'baz');

$this->assertFileExists($filename);
$this->assertFileExists($linknameA);
$this->assertFileExists($linknameB);
$this->assertStringEqualsFile($filename, 'foobarbaz');
$this->assertStringEqualsFile($linknameA, 'foobarbaz');
$this->assertStringEqualsFile($linknameB, 'foobarbaz');

$this->filesystem->remove($filename);
$this->filesystem->appendToFile($linknameB, 'foo');
$this->filesystem->appendToFile($linknameA, 'bar');

$this->assertFileExists($filename);
$this->assertStringEqualsFile($filename, 'foobar');
$this->assertStringEqualsFile($linknameA, 'foobar');
$this->assertStringEqualsFile($linknameB, 'foobar');
}

public function testAppendToFileWithScheme()
{
$scheme = 'file://';
Expand Down

0 comments on commit 38d3a96

Please sign in to comment.