[HttpKernel] changed the fragment handler to explicitely disallow non-scalar in generated URIs (refs #8263)

This commit is contained in:
Fabien Potencier 2013-07-08 08:42:57 +02:00
parent afd79eae83
commit 70f3399f7e
3 changed files with 45 additions and 13 deletions

View File

@ -52,7 +52,7 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
$reference = null;
if ($uri instanceof ControllerReference) {
$reference = $uri;
$uri = $this->generateFragmentUri($uri, $request);
$uri = $this->generateFragmentUri($uri, $request, false);
}
$subRequest = $this->createSubRequest($uri, $request);

View File

@ -40,12 +40,17 @@ abstract class RoutableFragmentRenderer implements FragmentRendererInterface
* Generates a fragment URI for a given controller.
*
* @param ControllerReference $reference A ControllerReference instance
* @param Request $request A Request instance
* @param Request $request A Request instance
* @param Boolean $strict Whether to allow non-scalar attributes or not
*
* @return string A fragment URI
*/
protected function generateFragmentUri(ControllerReference $reference, Request $request)
protected function generateFragmentUri(ControllerReference $reference, Request $request, $strict = true)
{
if ($strict) {
$this->checkNonScalar($reference->attributes);
}
if (!isset($reference->attributes['_format'])) {
$reference->attributes['_format'] = $request->getRequestFormat();
}
@ -56,4 +61,17 @@ abstract class RoutableFragmentRenderer implements FragmentRendererInterface
return $request->getUriForPath($this->fragmentPath.'?'.http_build_query($reference->query, '', '&'));
}
private function checkNonScalar($values)
{
foreach ($values as $value) {
if (is_array($value)) {
$this->checkNonScalar($value);
}
if (!is_scalar($value)) {
throw new \LogicException('Controller attributes cannot contain non-scalar values.');
}
}
}
}

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\HttpKernel\Fragment\Tests\FragmentRenderer;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ControllerReference;
use Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer;
class RoutableFragmentRendererTest extends \PHPUnit_Framework_TestCase
{
@ -22,7 +21,7 @@ class RoutableFragmentRendererTest extends \PHPUnit_Framework_TestCase
*/
public function testGenerateFragmentUri($uri, $controller)
{
$this->assertEquals($uri, $this->getRenderer()->doGenerateFragmentUri($controller, Request::create('/')));
$this->assertEquals($uri, $this->callGenerateFragmentUriMethod($controller, Request::create('/')));
}
public function getGenerateFragmentUriData()
@ -33,6 +32,7 @@ class RoutableFragmentRendererTest extends \PHPUnit_Framework_TestCase
array('http://localhost/_fragment?_path=foo%3Dfoo%26_format%3Djson%26_controller%3Dcontroller', new ControllerReference('controller', array('foo' => 'foo', '_format' => 'json'), array())),
array('http://localhost/_fragment?bar=bar&_path=foo%3Dfoo%26_format%3Dhtml%26_controller%3Dcontroller', new ControllerReference('controller', array('foo' => 'foo'), array('bar' => 'bar'))),
array('http://localhost/_fragment?foo=foo&_path=_format%3Dhtml%26_controller%3Dcontroller', new ControllerReference('controller', array(), array('foo' => 'foo'))),
array('http://localhost/_fragment?_path=foo%255B0%255D%3Dfoo%26foo%255B1%255D%3Dbar%26_format%3Dhtml%26_controller%3Dcontroller', new ControllerReference('controller', array('foo' => array('foo', 'bar')), array())),
);
}
@ -42,22 +42,36 @@ class RoutableFragmentRendererTest extends \PHPUnit_Framework_TestCase
$request->attributes->set('_format', 'json');
$controller = new ControllerReference('controller', array(), array());
$this->assertEquals('http://localhost/_fragment?_path=_format%3Djson%26_controller%3Dcontroller', $this->getRenderer()->doGenerateFragmentUri($controller, $request));
$this->assertEquals('http://localhost/_fragment?_path=_format%3Djson%26_controller%3Dcontroller', $this->callGenerateFragmentUriMethod($controller, $request));
}
private function getRenderer()
/**
* @expectedException LogicException
*/
public function testGenerateFragmentUriWithObject()
{
return new Renderer();
$controller = new ControllerReference('controller', array('foo' => new Foo(), 'bar' => 'bar'), array());
$this->callGenerateFragmentUriMethod($controller, Request::create('/'));
}
private function callGenerateFragmentUriMethod(ControllerReference $reference, Request $request)
{
$renderer = $this->getMockForAbstractClass('Symfony\Component\HttpKernel\Fragment\RoutableFragmentRenderer');
$r = new \ReflectionObject($renderer);
$m = $r->getMethod('generateFragmentUri');
$m->setAccessible(true);
return $m->invoke($renderer, $reference, $request);
}
}
class Renderer extends RoutableFragmentRenderer
class Foo
{
public function render($uri, Request $request, array $options = array()) {}
public function getName() {}
public $foo;
public function doGenerateFragmentUri(ControllerReference $reference, Request $request)
public function getFoo()
{
return parent::generateFragmentUri($reference, $request);
return $this->foo;
}
}