Skip to content

Commit 4aa8b46

Browse files
ausinicolas-grekas
authored andcommitted
[Filesystem] Follow symlinks when dumping files
1 parent fb23a49 commit 4aa8b46

File tree

2 files changed

+71
-2
lines changed

2 files changed

+71
-2
lines changed

src/Symfony/Component/Filesystem/Filesystem.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,12 @@ public function dumpFile(string $filename, $content)
669669

670670
$dir = \dirname($filename);
671671

672+
if (is_link($filename) && $linkTarget = $this->readlink($filename)) {
673+
$this->dumpFile(Path::makeAbsolute($linkTarget, $dir), $content);
674+
675+
return;
676+
}
677+
672678
if (!is_dir($dir)) {
673679
$this->mkdir($dir);
674680
}

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

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,14 +1091,16 @@ public function testReadBrokenLink()
10911091
{
10921092
$this->markAsSkippedIfSymlinkIsMissing();
10931093

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

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

1101+
touch($file);
11011102
$this->filesystem->symlink($file, $link);
1103+
$this->filesystem->remove($file);
11021104

11031105
$this->assertEquals($file, $this->filesystem->readlink($link));
11041106
$this->assertNull($this->filesystem->readlink($link, true));
@@ -1605,6 +1607,38 @@ public function testDumpFileOverwritesAnExistingFile()
16051607
$this->assertStringEqualsFile($filename, 'bar');
16061608
}
16071609

1610+
public function testDumpFileFollowsSymlink()
1611+
{
1612+
$filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo.txt';
1613+
file_put_contents($filename, 'FOO BAR');
1614+
$linknameA = $this->workspace.\DIRECTORY_SEPARATOR.'bar.txt';
1615+
$linknameB = $this->workspace.\DIRECTORY_SEPARATOR.'baz.txt';
1616+
$this->filesystem->symlink($filename, $linknameA);
1617+
$this->filesystem->symlink($linknameA, $linknameB);
1618+
1619+
$this->filesystem->dumpFile($linknameB, 'bar');
1620+
1621+
$this->assertFileExists($filename);
1622+
$this->assertFileExists($linknameA);
1623+
$this->assertFileExists($linknameB);
1624+
$this->assertStringEqualsFile($filename, 'bar');
1625+
$this->assertStringEqualsFile($linknameA, 'bar');
1626+
$this->assertStringEqualsFile($linknameB, 'bar');
1627+
1628+
// Windows does not support reading "broken" symlinks in PHP < 7.4.0
1629+
if ('\\' === \DIRECTORY_SEPARATOR && \PHP_VERSION_ID < 70400) {
1630+
return;
1631+
}
1632+
1633+
$this->filesystem->remove($filename);
1634+
$this->filesystem->dumpFile($linknameB, 'baz');
1635+
1636+
$this->assertFileExists($filename);
1637+
$this->assertStringEqualsFile($filename, 'baz');
1638+
$this->assertStringEqualsFile($linknameA, 'baz');
1639+
$this->assertStringEqualsFile($linknameB, 'baz');
1640+
}
1641+
16081642
public function testDumpFileWithFileScheme()
16091643
{
16101644
$scheme = 'file://';
@@ -1678,6 +1712,35 @@ public function testAppendToFileWithResource()
16781712
}
16791713
}
16801714

1715+
public function testAppendToFileFollowsSymlink()
1716+
{
1717+
$filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo.txt';
1718+
file_put_contents($filename, 'foo');
1719+
$linknameA = $this->workspace.\DIRECTORY_SEPARATOR.'bar.txt';
1720+
$linknameB = $this->workspace.\DIRECTORY_SEPARATOR.'baz.txt';
1721+
$this->filesystem->symlink($filename, $linknameA);
1722+
$this->filesystem->symlink($linknameA, $linknameB);
1723+
1724+
$this->filesystem->appendToFile($linknameA, 'bar');
1725+
$this->filesystem->appendToFile($linknameB, 'baz');
1726+
1727+
$this->assertFileExists($filename);
1728+
$this->assertFileExists($linknameA);
1729+
$this->assertFileExists($linknameB);
1730+
$this->assertStringEqualsFile($filename, 'foobarbaz');
1731+
$this->assertStringEqualsFile($linknameA, 'foobarbaz');
1732+
$this->assertStringEqualsFile($linknameB, 'foobarbaz');
1733+
1734+
$this->filesystem->remove($filename);
1735+
$this->filesystem->appendToFile($linknameB, 'foo');
1736+
$this->filesystem->appendToFile($linknameA, 'bar');
1737+
1738+
$this->assertFileExists($filename);
1739+
$this->assertStringEqualsFile($filename, 'foobar');
1740+
$this->assertStringEqualsFile($linknameA, 'foobar');
1741+
$this->assertStringEqualsFile($linknameB, 'foobar');
1742+
}
1743+
16811744
public function testAppendToFileWithScheme()
16821745
{
16831746
$scheme = 'file://';

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy