From ef1206964eb77cba2eb27f593eefe2575a9b84b0 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Tue, 6 Aug 2019 19:34:24 -0700 Subject: [PATCH] [Filesystem] Add $suffix argument to tempnam() Fixes #33002 --- src/Symfony/Component/Filesystem/CHANGELOG.md | 1 + src/Symfony/Component/Filesystem/Filesystem.php | 8 +++++--- .../Filesystem/Tests/FilesystemTest.php | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Filesystem/CHANGELOG.md b/src/Symfony/Component/Filesystem/CHANGELOG.md index d103bc2c57..4a0755bfe0 100644 --- a/src/Symfony/Component/Filesystem/CHANGELOG.md +++ b/src/Symfony/Component/Filesystem/CHANGELOG.md @@ -10,6 +10,7 @@ CHANGELOG ----- * support for passing a `null` value to `Filesystem::isAbsolutePath()` is deprecated and will be removed in 5.0 + * `tempnam()` now accepts a third argument `$suffix`. 4.3.0 ----- diff --git a/src/Symfony/Component/Filesystem/Filesystem.php b/src/Symfony/Component/Filesystem/Filesystem.php index 3fa4d6bb51..c8d3344fde 100644 --- a/src/Symfony/Component/Filesystem/Filesystem.php +++ b/src/Symfony/Component/Filesystem/Filesystem.php @@ -584,15 +584,17 @@ class Filesystem * * @param string $prefix The prefix of the generated temporary filename * Note: Windows uses only the first three characters of prefix + * @param string $suffix The suffix of the generated temporary filename * * @return string The new temporary filename (with path), or throw an exception on failure */ - public function tempnam(string $dir, string $prefix) + public function tempnam(string $dir, string $prefix/*, string $suffix = ''*/) { + $suffix = \func_num_args() > 2 ? func_get_arg(2) : ''; list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir); // If no scheme or scheme is "file" or "gs" (Google Cloud) create temp file in local filesystem - if (null === $scheme || 'file' === $scheme || 'gs' === $scheme) { + if ((null === $scheme || 'file' === $scheme || 'gs' === $scheme) && '' === $suffix) { $tmpFile = @tempnam($hierarchy, $prefix); // If tempnam failed or no scheme return the filename otherwise prepend the scheme @@ -610,7 +612,7 @@ class Filesystem // Loop until we create a valid temp file or have reached 10 attempts for ($i = 0; $i < 10; ++$i) { // Create a unique filename - $tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true); + $tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true).$suffix; // Use fopen instead of file_exists as some streams do not support stat // Use mode 'x+' to atomically check existence and create to avoid a TOCTOU vulnerability diff --git a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php index dcd3c61406..79b2f61d0c 100644 --- a/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php +++ b/src/Symfony/Component/Filesystem/Tests/FilesystemTest.php @@ -1509,6 +1509,22 @@ class FilesystemTest extends FilesystemTestCase @unlink($filename); } + public function testTempnamWithSuffix() + { + $dirname = $this->workspace; + $filename = $this->filesystem->tempnam($dirname, 'foo', '.bar'); + $this->assertStringEndsWith('.bar', $filename); + $this->assertFileExists($filename); + } + + public function testTempnamWithSuffix0() + { + $dirname = $this->workspace; + $filename = $this->filesystem->tempnam($dirname, 'foo', '0'); + $this->assertStringEndsWith('0', $filename); + $this->assertFileExists($filename); + } + public function testDumpFile() { $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'baz.txt';