From 9872d26c9c68c525a7a40cb5d57157556749209d Mon Sep 17 00:00:00 2001 From: Al Ganiev Date: Sun, 9 Sep 2012 23:24:25 +1100 Subject: [PATCH] [HttpFoundation] Fix name sanitization after perfoming move --- .../Component/HttpFoundation/File/File.php | 18 +++++++++- .../HttpFoundation/File/UploadedFile.php | 6 ++-- .../HttpFoundation/File/FileTest.php | 35 +++++++++++++++++++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/File/File.php b/src/Symfony/Component/HttpFoundation/File/File.php index ab366161029a..43b8c0d265a2 100644 --- a/src/Symfony/Component/HttpFoundation/File/File.php +++ b/src/Symfony/Component/HttpFoundation/File/File.php @@ -532,7 +532,7 @@ public function move($directory, $name = null) throw new FileException(sprintf('Unable to write in the "%s" directory', $directory)); } - $target = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : basename($name)); + $target = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : $this->getName($name)); if (!@rename($this->getPathname(), $target)) { $error = error_get_last(); @@ -543,4 +543,20 @@ public function move($directory, $name = null) return new File($target); } + + /** + * Returns locale independent base name of the given path. + * + * @param string $name The new file name + * + * @return string containing + */ + protected function getName($name) + { + $originalName = str_replace('\\', '/', $name); + $pos = strrpos($originalName, '/'); + $originalName = false === $pos ? $originalName : substr($originalName, $pos + 1); + + return $originalName; + } } diff --git a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php index e3469ade06a4..7b337da9ffd9 100644 --- a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php +++ b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php @@ -94,9 +94,7 @@ public function __construct($path, $originalName, $mimeType = null, $size = null throw new FileException(sprintf('Unable to create UploadedFile because "file_uploads" is disabled in your php.ini file (%s)', get_cfg_var('cfg_file_path'))); } - $originalName = str_replace('\\', '/', $originalName); - $pos = strrpos($originalName, '/'); - $this->originalName = false === $pos ? $originalName : substr($originalName, $pos + 1); + $this->originalName = $this->getName($originalName); $this->mimeType = $mimeType ?: 'application/octet-stream'; $this->size = $size; $this->error = $error ?: UPLOAD_ERR_OK; @@ -168,7 +166,7 @@ public function getError() /** * Returns whether the file was uploaded successfully. * - * @return Boolean True if no error occurred during uploading + * @return Boolean True if no error occurred during uploading * * @api */ diff --git a/tests/Symfony/Tests/Component/HttpFoundation/File/FileTest.php b/tests/Symfony/Tests/Component/HttpFoundation/File/FileTest.php index b6f29c16b42d..8e0ead62d03c 100644 --- a/tests/Symfony/Tests/Component/HttpFoundation/File/FileTest.php +++ b/tests/Symfony/Tests/Component/HttpFoundation/File/FileTest.php @@ -91,6 +91,41 @@ public function testMoveWithNewName() @unlink($targetPath); } + public function getFilenameFixtures() + { + return array( + array('original.gif', 'original.gif'), + array('..\\..\\original.gif', 'original.gif'), + array('../../original.gif', 'original.gif'), + array('файлfile.gif', 'файлfile.gif'), + array('..\\..\\файлfile.gif', 'файлfile.gif'), + array('../../файлfile.gif', 'файлfile.gif'), + ); + } + + /** + * @dataProvider getFilenameFixtures + */ + public function testMoveWithNonLatinName($filename, $sanitizedFilename) + { + $path = __DIR__.'/Fixtures/'.$sanitizedFilename; + $targetDir = __DIR__.'/Fixtures/directory/'; + $targetPath = $targetDir.$sanitizedFilename; + @unlink($path); + @unlink($targetPath); + copy(__DIR__.'/Fixtures/test.gif', $path); + + $file = new File($path); + $movedFile = $file->move($targetDir,$filename); + $this->assertInstanceOf('Symfony\Component\HttpFoundation\File\File', $movedFile); + + $this->assertTrue(file_exists($targetPath)); + $this->assertFalse(file_exists($path)); + $this->assertEquals(realpath($targetPath), $movedFile->getRealPath()); + + @unlink($targetPath); + } + public function testMoveToAnUnexistentDirectory() { $sourcePath = __DIR__.'/Fixtures/test.copy.gif';