From 576a778f27057f76fb59efbfcf4d48397259a949 Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Mon, 25 May 2020 11:45:33 +0200 Subject: [PATCH 1/4] Verify bytes written in Filesystem::dumpFile() --- src/Symfony/Component/Filesystem/Filesystem.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index e2812f8e2252b..ced754b66e91b 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|array $content The data to write into the file * * @throws IOException if the file cannot be written to */ @@ -684,8 +684,14 @@ 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); + if (\is_resource($content)) { + $expectedSize = fstat($content)['size']; + } else { + $expectedSize = array_sum(array_map('strlen', (array) $content)); + } + + if ($expectedSize !== ($actualSize = @file_put_contents($tmpFile, $content))) { + 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()); From 70cc2dbd6cae56b60fee35b97ccc486bfceec584 Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Mon, 25 May 2020 12:09:54 +0200 Subject: [PATCH 2/4] Support dumping partial files --- src/Symfony/Component/Filesystem/Filesystem.php | 2 +- .../Component/Filesystem/Tests/FilesystemTest.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index ced754b66e91b..6169933514a5c 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -685,7 +685,7 @@ public function dumpFile($filename, $content) $tmpFile = $this->tempnam($dir, basename($filename)); if (\is_resource($content)) { - $expectedSize = fstat($content)['size']; + $expectedSize = fstat($content)['size'] - ftell($content); } else { $expectedSize = array_sum(array_map('strlen', (array) $content)); } diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 8ac80437fe5dc..2043e4b49b0c5 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1505,6 +1505,21 @@ 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'); + } + public function testDumpFileOverwritesAnExistingFile() { $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo.txt'; From 29938785b19ebee0539db6775731583192186ba1 Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Wed, 3 Jun 2020 10:51:55 +0200 Subject: [PATCH 3/4] =?UTF-8?q?Don=E2=80=99t=20advertise=20array?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Symfony/Component/Filesystem/Filesystem.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 6169933514a5c..a20bda1eb75aa 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|resource|array $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 */ From 820c025ee4ebfde02e272847e7ee5f8ffc9de1e9 Mon Sep 17 00:00:00 2001 From: Lars Strojny Date: Tue, 9 Jun 2020 15:43:02 +0200 Subject: [PATCH 4/4] Test with https wrappers --- src/Symfony/Component/Filesystem/Filesystem.php | 10 ++++++++-- .../Filesystem/Tests/FilesystemTest.php | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index a20bda1eb75aa..3e3bd6fd3addc 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -684,13 +684,19 @@ public function dumpFile($filename, $content) // when the filesystem supports chmod. $tmpFile = $this->tempnam($dir, basename($filename)); + $expectedSize = false; + if (\is_resource($content)) { - $expectedSize = fstat($content)['size'] - ftell($content); + $stat = fstat($content); + if (false !== $stat) { + $expectedSize = $stat['size'] - ftell($content); + } } else { $expectedSize = array_sum(array_map('strlen', (array) $content)); } - if ($expectedSize !== ($actualSize = @file_put_contents($tmpFile, $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); } diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index 2043e4b49b0c5..8666de00b99a6 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1520,6 +1520,23 @@ public function testDumpPartialFileWithResource() $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