8000 [FrameworkBundle] restricted the type of controllers that can be exec… · loicfrering/symfony@1f8c501 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1f8c501

Browse files
committed
[FrameworkBundle] restricted the type of controllers that can be executed by InternalController
1 parent d90e55c commit 1f8c501

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

src/Symfony/Bundle/FrameworkBundle/Controller/InternalController.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,35 @@ class InternalController extends ContainerAware
3131
*/
3232
public function indexAction($path, $controller)
3333
{
34+
// safeguard
35+
if (!is_string($controller)) {
36+
throw new \RuntimeException('A Controller must be a string.');
37+
}
38+
39+
// check that the controller looks like a controller
40+
if (false === strpos($controller, '::')) {
41+
$count = substr_count($controller, ':');
42+
if (2 == $count) {
43+
// the convention already enforces the Controller suffix
44+
} elseif (1 == $count) {
45+
// controller in the service:method notation
46+
list($service, $method) = explode(':', $controller, 2);
47+
$class = get_class($this->container->get($service));
48+
49+
if (!preg_match('/Controller$/', $class)) {
50+
throw new \RuntimeException('A Controller class name must end with Controller.');
51+
}
52+
} else {
53+
throw new \LogicException('Unable to parse the Controller name.');
54+
}
55+
} else {
56+
list($class, $method) = explode('::', $controller, 2);
57+
58+
if (!preg_match('/Controller$/', $class)) {
59+
throw new \RuntimeException('A Controller class name must end with Controller.');
60+
}
61+
}
62+
3463
$request = $this->container->get('request');
3564
$attributes = $request->attributes;
3665

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;
13+
14+
use Symfony\Bundle\FrameworkBundle\Controller\InternalController;
15+
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
16+
use Symfony\Component\HttpFoundation\Request;
17+
18+
class InternalControllerTest extends TestCase
19+
{
20+
/**
21+
* @expectedException \RuntimeException
22+
* @expectedExceptionMessage A Controller class name must end with Controller.
23+
*/
24+
public function testWithAClassMethodController()
25+
{
26+
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
27+
28+
$controller = new InternalController();
29+
$controller->setContainer($container);
30+
31+
$controller->indexAction('/', 'Symfony\Component\HttpFoundation\Request::getPathInfo');
32+
}
33+
34+
/**
35+
* @expectedException \RuntimeException
36+
* @expectedExceptionMessage A Controller class name must end with Controller.
37+
*/
38+
public function testWithAServiceController()
39+
{
40+
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
41+
$container
42+
->expects($this->once())
43+
->method('get')
44+
->will($this->returnValue(new Request()))
45+
;
46+
47+
$controller = new InternalController();
48+
$controller->setContainer($container);
49+
50+
$controller->indexAction('/', 'service:method');
51+
}
52+
}

0 commit comments

Comments
 (0)
0