diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index e2812f8e2252b..3e3bd6fd3addc 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -663,8 +663,8 @@ public function tempnam($dir, $prefix) /** * Atomically dumps content into a file. * - * @param string $filename The file to be written to - * @param string $content The data to write into the file + * @param string $filename The file to be written to + * @param string|resource $content The data to write into the file * * @throws IOException if the file cannot be written to */ @@ -684,8 +684,20 @@ public function dumpFile($filename, $content) // when the filesystem supports chmod. $tmpFile = $this->tempnam($dir, basename($filename)); - if (false === @file_put_contents($tmpFile, $content)) { - throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename); + $expectedSize = false; + + if (\is_resource($content)) { + $stat = fstat($content); + if (false !== $stat) { + $expectedSize = $stat['size'] - ftell($content); + } + } else { + $expectedSize = array_sum(array_map('strlen', (array) $content)); + } + + $actualSize = @file_put_contents($tmpFile, $content); + if ((false === $expectedSize && false === $actualSize) && ($actualSize !== $expectedSize)) { + throw new IOException(sprintf('Failed to write file "%s". Wrote %d of %d bytes.', $filename, $actualSize, $expectedSize), 0, null, $filename); } @chmod($tmpFile, file_exists($filename) ? fileperms($filename) : 0666 & ~umask()); diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 8ac80437fe5dc..8666de00b99a6 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1505,6 +1505,38 @@ public function testDumpFileWithResource() $this->assertStringEqualsFile($filename, 'bar'); } + public function testDumpPartialFileWithResource() + { + $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'baz.txt'; + + $resource = fopen('php://memory', 'rw'); + fwrite($resource, 'bar'); + fseek($resource, 1); + + $this->filesystem->dumpFile($filename, $resource); + + fclose($resource); + $this->assertFileExists($filename); + $this->assertStringEqualsFile($filename, 'ar'); + } + + /** + * @group network + */ + public function testDumpFileWithHttpStream() + { + if (!\in_array('https', stream_get_wrappers())) { + $this->markTestSkipped('"https" stream wrapper is not enabled.'); + } + $sourceFilePath = 'https://symfony.com/images/common/logo/logo_symfony_header.png'; + $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'dump_target_file'; + + $this->filesystem->dumpFile($targetFilePath, fopen($sourceFilePath, 'rb')); + + $this->assertFileExists($targetFilePath); + $this->assertEquals(file_get_contents($sourceFilePath), file_get_contents($targetFilePath)); + } + public function testDumpFileOverwritesAnExistingFile() { $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo.txt'; 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