From 9f9f2300d782f272577d60deed4dd1d208937ca2 Mon Sep 17 00:00:00 2001 From: Javier Spagnoletti Date: Mon, 16 Feb 2015 14:04:09 -0300 Subject: [PATCH 1/5] [2.3] [HttpFoundation] fixed param order for Nginx's x-accel-redirect | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | kinda | Deprecations? | no | Tests pass? | yes | Fixed tickets | #13502 | License | MIT | Doc PR | n/a fixes #13502 Inverted path and location directives for x-accel-redirect header Before: ```proxy_set_header X-Accel-Mapping /internal/=/var/www/example.com/``` After: ```proxy_set_header X-Accel-Mapping /var/www/example.com/=/internal/``` --- src/Symfony/Component/HttpFoundation/BinaryFileResponse.php | 5 +++-- .../HttpFoundation/Tests/BinaryFileResponseTest.php | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php index bcb4d7077b..69afbe1c84 100644 --- a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php +++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php @@ -194,12 +194,13 @@ class BinaryFileResponse extends Response $path = $this->file->getRealPath(); if (strtolower($type) == 'x-accel-redirect') { // Do X-Accel-Mapping substitutions. + // @link http://wiki.nginx.org/X-accel#X-Accel-Redirect foreach (explode(',', $request->headers->get('X-Accel-Mapping', '')) as $mapping) { $mapping = explode('=', $mapping, 2); if (2 == count($mapping)) { - $location = trim($mapping[0]); - $pathPrefix = trim($mapping[1]); + $pathPrefix = trim($mapping[0]); + $location = trim($mapping[1]); if (substr($path, 0, strlen($pathPrefix)) == $pathPrefix) { $path = $location.substr($path, strlen($pathPrefix)); diff --git a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php index 631f25ff1d..1d8731c665 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php @@ -222,8 +222,8 @@ class BinaryFileResponseTest extends ResponseTestCase public function getSampleXAccelMappings() { return array( - array('/var/www/var/www/files/foo.txt', '/files/=/var/www/', '/files/var/www/files/foo.txt'), - array('/home/foo/bar.txt', '/files/=/var/www/,/baz/=/home/foo/', '/baz/bar.txt'), + array('/var/www/var/www/files/foo.txt', '/var/www/=/files/', '/files/var/www/files/foo.txt'), + array('/home/foo/bar.txt', '/var/www/=/files/,/home/foo/=/baz/', '/baz/bar.txt'), ); } From 87800ae47e64429f2544b798575d1cc1d4e5464a Mon Sep 17 00:00:00 2001 From: Nikita Starshinov Date: Thu, 19 Feb 2015 16:58:07 +0300 Subject: [PATCH 2/5] minor #13377 [Console] Change greater by greater or equal for isFresh in FileResource --- .../Component/Config/Resource/FileResource.php | 2 +- .../Component/Config/Tests/ConfigCacheTest.php | 2 +- .../Config/Tests/Resource/FileResourceTest.php | 11 +++++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index b828e7d37f..4c00ae4140 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -60,7 +60,7 @@ class FileResource implements ResourceInterface, \Serializable return false; } - return filemtime($this->resource) < $timestamp; + return filemtime($this->resource) <= $timestamp; } public function serialize() diff --git a/src/Symfony/Component/Config/Tests/ConfigCacheTest.php b/src/Symfony/Component/Config/Tests/ConfigCacheTest.php index 27434f13c9..8508763185 100644 --- a/src/Symfony/Component/Config/Tests/ConfigCacheTest.php +++ b/src/Symfony/Component/Config/Tests/ConfigCacheTest.php @@ -128,7 +128,7 @@ class ConfigCacheTest extends \PHPUnit_Framework_TestCase private function makeCacheStale() { - touch($this->cacheFile, time() - 3600); + touch($this->cacheFile, filemtime($this->resourceFile) - 3600); } private function generateMetaFile() diff --git a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php index 1f1ddee23f..d152806d0c 100644 --- a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php @@ -17,11 +17,13 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase { protected $resource; protected $file; + protected $time; protected function setUp() { $this->file = realpath(sys_get_temp_dir()).'/tmp.xml'; - touch($this->file); + $this->time = time(); + touch($this->file, $this->time); $this->resource = new FileResource($this->file); } @@ -42,11 +44,12 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase public function testIsFresh() { - $this->assertTrue($this->resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed'); - $this->assertFalse($this->resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated'); + $this->assertTrue($this->resource->isFresh($this->time), '->isFresh() returns true if the resource has not changed in same second'); + $this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed'); + $this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated'); $resource = new FileResource('/____foo/foobar'.rand(1, 999999)); - $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist'); + $this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource does not exist'); } public function testSerializeUnserialize() From 0ebcf639c3998924b1fd26cc1d52ae4d5aff5b94 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 23 Feb 2015 09:29:32 +0100 Subject: [PATCH 3/5] [HttpKernel] Throw double-bounce exceptions --- .../HttpKernel/EventListener/ExceptionListener.php | 8 ++++---- .../Tests/EventListener/ExceptionListenerTest.php | 12 +++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php index 74544a9fd1..a54fe45e9f 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php @@ -67,13 +67,13 @@ class ExceptionListener implements EventSubscriberInterface try { $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, true); } catch (\Exception $e) { - $this->logException($exception, sprintf('Exception thrown when handling an exception (%s: %s)', get_class($e), $e->getMessage()), false); + $this->logException($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), false); // set handling to false otherwise it wont be able to handle further more $handling = false; - // re-throw the exception from within HttpKernel as this is a catch-all - return; + // throwing $e, not $exception, is on purpose: fixing error handling code paths is the most important + throw $e; } $event->setResponse($response); @@ -91,7 +91,7 @@ class ExceptionListener implements EventSubscriberInterface /** * Logs an exception. * - * @param \Exception $exception The original \Exception instance + * @param \Exception $exception The \Exception instance * @param string $message The error message to log * @param bool $original False when the handling of the exception thrown another exception */ diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php index 28f64e82c7..86244df0fc 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php @@ -54,8 +54,9 @@ class ExceptionListenerTest extends \PHPUnit_Framework_TestCase try { $l->onKernelException($event2); - } catch (\Exception $e) { - $this->assertSame('foo', $e->getMessage()); + $this->fail('RuntimeException expected'); + } catch (\RuntimeException $e) { + $this->assertSame('bar', $e->getMessage()); } } @@ -73,8 +74,9 @@ class ExceptionListenerTest extends \PHPUnit_Framework_TestCase try { $l->onKernelException($event2); - } catch (\Exception $e) { - $this->assertSame('foo', $e->getMessage()); + $this->fail('RuntimeException expected'); + } catch (\RuntimeException $e) { + $this->assertSame('bar', $e->getMessage()); } $this->assertEquals(3, $logger->countErrors()); @@ -137,6 +139,6 @@ class TestKernelThatThrowsException implements HttpKernelInterface { public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true) { - throw new \Exception('bar'); + throw new \RuntimeException('bar'); } } From 46bea3ab30594c64c2d493af94b6ff1d70928cca Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 25 Feb 2015 08:45:04 +0100 Subject: [PATCH 4/5] [VarDumper] Workaround stringy numeric keys --- .../VarDumper/Cloner/AbstractCloner.php | 10 +- .../VarDumper/Tests/VarClonerTest.php | 94 +++++++++++++++++++ 2 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 src/Symfony/Component/VarDumper/Tests/VarClonerTest.php diff --git a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php index 49476d5bec..63e683cb15 100644 --- a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php +++ b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php @@ -199,15 +199,17 @@ abstract class AbstractCloner implements ClonerInterface } if ($classInfo[1]) { - $a = $this->callCaster(function ($obj) {return $obj->__debugInfo();}, $obj, array(), null, $isNested); + $p = $this->callCaster(function ($obj) {return $obj->__debugInfo();}, $obj, array(), null, $isNested); } else { - $a = (array) $obj; + $p = (array) $obj; } - foreach ($a as $k => $p) { + $a = array(); + foreach ($p as $k => $p) { if (!isset($k[0]) || ("\0" !== $k[0] && !$classInfo[2]->hasProperty($k))) { - unset($a[$k]); $a["\0+\0".$k] = $p; + } else { + $a[$k] = $p; } } diff --git a/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php b/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php new file mode 100644 index 0000000000..0e28ebac06 --- /dev/null +++ b/src/Symfony/Component/VarDumper/Tests/VarClonerTest.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests; + +use Symfony\Component\VarDumper\Cloner\VarCloner; + +/** + * @author Nicolas Grekas + */ +class VarClonerTest extends \PHPUnit_Framework_TestCase +{ + public function testClone() + { + $json = json_decode('{"1":{"var":"val"},"2":{"var":"val"}}'); + + $cloner = new VarCloner(); + $clone = $cloner->cloneVar($json); + + $expected = << Array + ( + [0] => Array + ( + [0] => Symfony\Component\VarDumper\Cloner\Stub Object + ( + [type] => object + [class] => stdClass + [value] => + [cut] => 0 + [handle] => %d + [refCount] => 0 + [position] => 1 + ) + + ) + + [1] => Array + ( + [\000+\0001] => Symfony\Component\VarDumper\Cloner\Stub Object + ( + [type] => object + [class] => stdClass + [value] => + [cut] => 0 + [handle] => %d + [refCount] => 0 + [position] => 2 + ) + + [\000+\0002] => Symfony\Component\VarDumper\Cloner\Stub Object + ( + [type] => object + [class] => stdClass + [value] => + [cut] => 0 + [handle] => %d + [refCount] => 0 + [position] => 3 + ) + + ) + + [2] => Array + ( + [\000+\000var] => val + ) + + [3] => Array + ( + [\000+\000var] => val + ) + + ) + + [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 + [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 + [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 +) + +EOTXT; + $this->assertStringMatchesFormat($expected, print_r($clone, true)); + } +} From 9b3421f18a030b2b444d366fc8ea11ca30c82f37 Mon Sep 17 00:00:00 2001 From: Mikael Pajunen Date: Tue, 24 Feb 2015 00:10:57 +0200 Subject: [PATCH 5/5] [Form] NativeRequestHandler file handling fix --- .../Component/Form/NativeRequestHandler.php | 4 +- .../Form/Tests/AbstractRequestHandlerTest.php | 46 ++++++++++++++++++- .../HttpFoundationRequestHandlerTest.php | 4 +- .../Component/Form/Tests/Fixtures/foo2 | 0 .../Component/Form/Tests/Fixtures/foo3 | 0 .../Form/Tests/NativeRequestHandlerTest.php | 6 +-- 6 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 src/Symfony/Component/Form/Tests/Fixtures/foo2 create mode 100644 src/Symfony/Component/Form/Tests/Fixtures/foo3 diff --git a/src/Symfony/Component/Form/NativeRequestHandler.php b/src/Symfony/Component/Form/NativeRequestHandler.php index ea748d6161..a888967bb3 100644 --- a/src/Symfony/Component/Form/NativeRequestHandler.php +++ b/src/Symfony/Component/Form/NativeRequestHandler.php @@ -98,8 +98,8 @@ class NativeRequestHandler implements RequestHandlerInterface } $fixedFiles = array(); - foreach ($_FILES as $name => $file) { - $fixedFiles[$name] = self::stripEmptyFiles(self::fixPhpFilesArray($file)); + foreach ($_FILES as $fileKey => $file) { + $fixedFiles[$fileKey] = self::stripEmptyFiles(self::fixPhpFilesArray($file)); } if ('' === $name) { diff --git a/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php b/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php index b017db90d0..e4d63c2a94 100644 --- a/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php +++ b/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php @@ -266,6 +266,50 @@ abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase $this->requestHandler->handleRequest($form, $this->request); } + /** + * @dataProvider methodExceptGetProvider + */ + public function testSubmitMultipleFiles($method) + { + $form = $this->getMockForm('param1', $method); + $file = $this->getMockFile(); + + $this->setRequestData($method, array( + 'param1' => null, + ), array( + 'param2' => $this->getMockFile('2'), + 'param1' => $file, + 'param3' => $this->getMockFile('3'), + )); + + $form->expects($this->once()) + ->method('submit') + ->with($file, 'PATCH' !== $method); + + $this->requestHandler->handleRequest($form, $this->request); + } + + /** + * @dataProvider methodExceptGetProvider + */ + public function testSubmitFileWithNamelessForm($method) + { + $form = $this->getMockForm(null, $method); + $file = $this->getMockFile(); + + $this->setRequestData($method, array( + '' => null, + ), array( + '' => $file, + )); + + $form->expects($this->once()) + ->method('submit') + ->with($file, 'PATCH' !== $method); + + $this->requestHandler->handleRequest($form, $this->request); + } + /** * @dataProvider getPostMaxSizeFixtures */ @@ -314,7 +358,7 @@ abstract class AbstractRequestHandlerTest extends \PHPUnit_Framework_TestCase abstract protected function getRequestHandler(); - abstract protected function getMockFile(); + abstract protected function getMockFile($suffix = ''); protected function getMockForm($name, $method = null, $compound = true) { diff --git a/src/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php b/src/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php index dcd26891c1..4d4ac86fe7 100644 --- a/src/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/HttpFoundation/HttpFoundationRequestHandlerTest.php @@ -46,8 +46,8 @@ class HttpFoundationRequestHandlerTest extends AbstractRequestHandlerTest return new HttpFoundationRequestHandler($this->serverParams); } - protected function getMockFile() + protected function getMockFile($suffix = '') { - return new UploadedFile(__DIR__.'/../../Fixtures/foo', 'foo'); + return new UploadedFile(__DIR__.'/../../Fixtures/foo'.$suffix, 'foo'.$suffix); } } diff --git a/src/Symfony/Component/Form/Tests/Fixtures/foo2 b/src/Symfony/Component/Form/Tests/Fixtures/foo2 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Symfony/Component/Form/Tests/Fixtures/foo3 b/src/Symfony/Component/Form/Tests/Fixtures/foo3 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Symfony/Component/Form/Tests/NativeRequestHandlerTest.php b/src/Symfony/Component/Form/Tests/NativeRequestHandlerTest.php index eac767f8c8..38580063e7 100644 --- a/src/Symfony/Component/Form/Tests/NativeRequestHandlerTest.php +++ b/src/Symfony/Component/Form/Tests/NativeRequestHandlerTest.php @@ -206,12 +206,12 @@ class NativeRequestHandlerTest extends AbstractRequestHandlerTest return new NativeRequestHandler($this->serverParams); } - protected function getMockFile() + protected function getMockFile($suffix = '') { return array( - 'name' => 'upload.txt', + 'name' => 'upload'.$suffix.'.txt', 'type' => 'text/plain', - 'tmp_name' => 'owfdskjasdfsa', + 'tmp_name' => 'owfdskjasdfsa'.$suffix, 'error' => UPLOAD_ERR_OK, 'size' => 100, );