diff --git a/src/Symfony/Component/HttpFoundation/File/File.php b/src/Symfony/Component/HttpFoundation/File/File.php index d3d20f583a..729d870cfc 100644 --- a/src/Symfony/Component/HttpFoundation/File/File.php +++ b/src/Symfony/Component/HttpFoundation/File/File.php @@ -106,6 +106,20 @@ class File extends \SplFileInfo * @api */ public function move($directory, $name = null) + { + $target = $this->getTargetFile($directory, $name); + + if (!@rename($this->getPathname(), $target)) { + $error = error_get_last(); + throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message']))); + } + + @chmod($target, 0666 & ~umask()); + + return $target; + } + + protected function getTargetFile($directory, $name = null) { if (!is_dir($directory)) { if (false === @mkdir($directory, 0777, true)) { @@ -117,14 +131,7 @@ class File extends \SplFileInfo $target = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : $this->getName($name)); - if (!@rename($this->getPathname(), $target)) { - $error = error_get_last(); - throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message']))); - } - - @chmod($target, 0666 & ~umask()); - - return new File($target); + return new File($target, false); } /** diff --git a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php index 69d653497a..d201e2dc03 100644 --- a/src/Symfony/Component/HttpFoundation/File/UploadedFile.php +++ b/src/Symfony/Component/HttpFoundation/File/UploadedFile.php @@ -189,8 +189,21 @@ class UploadedFile extends File */ public function move($directory, $name = null) { - if ($this->isValid() && ($this->test || is_uploaded_file($this->getPathname()))) { - return parent::move($directory, $name); + if ($this->isValid()) { + if ($this->test) { + return parent::move($directory, $name); + } elseif (is_uploaded_file($this->getPathname())) { + $target = $this->getTargetFile($directory, $name); + + if (!@move_uploaded_file($this->getPathname(), $target)) { + $error = error_get_last(); + throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message']))); + } + + @chmod($target, 0666 & ~umask()); + + return $target; + } } throw new FileException(sprintf('The file "%s" has not been uploaded via Http', $this->getPathname())); diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index f7b1c25b81..0daf81d723 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -974,6 +974,8 @@ class Request * * @return string * + * @throws \UnexpectedValueException when the host name is invalid + * * @api */ public function getHost() @@ -981,20 +983,24 @@ class Request if (self::$trustProxy && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) { $elements = explode(',', $host); - $host = trim($elements[count($elements) - 1]); - } else { - if (!$host = $this->headers->get('HOST')) { - if (!$host = $this->server->get('SERVER_NAME')) { - $host = $this->server->get('SERVER_ADDR', ''); - } + $host = $elements[count($elements) - 1]; + } elseif (!$host = $this->headers->get('HOST')) { + if (!$host = $this->server->get('SERVER_NAME')) { + $host = $this->server->get('SERVER_ADDR', ''); } } - // Remove port number from host - $host = preg_replace('/:\d+$/', '', $host); - + // trim and remove port number from host // host is lowercase as per RFC 952/2181 - return trim(strtolower($host)); + $host = strtolower(trim(preg_replace('/:\d+$/', '', $host))); + + // as the host can come from the user (HTTP_HOST and depending on the configuration, SERVER_NAME too can come from the user) + // check that it does not contain forbidden characters (see RFC 952 and RFC 2181) + if ($host && !preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host)) { + throw new \UnexpectedValueException('Invalid Host'); + } + + return $host; } /** diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index 07376cedb8..535ebfc9a3 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -560,9 +560,6 @@ class RequestTest extends \PHPUnit_Framework_TestCase $this->assertNull($request->getQueryString(), '->getQueryString() returns null for empty query string'); } - /** - * @covers Symfony\Component\HttpFoundation\Request::getHost - */ public function testGetHost() { $request = new Request(); @@ -586,6 +583,16 @@ class RequestTest extends \PHPUnit_Framework_TestCase $this->stopTrustingProxyData(); } + /** + * @expectedException RuntimeException + */ + public function testGetHostWithFakeHttpHostValue() + { + $request = new Request(); + $request->initialize(array(), array(), array(), array(), array(), array('HTTP_HOST' => 'www.host.com?query=string')); + $request->getHost(); + } + /** * @covers Symfony\Component\HttpFoundation\Request::setMethod * @covers Symfony\Component\HttpFoundation\Request::getMethod