Commit bc0570c8 authored by alexpott's avatar alexpott

Issue #2051877 by dawehner: Log error when people use invalid route parameters.

parent d238a401
......@@ -343,6 +343,10 @@ services:
arguments: ['@content_negotiation']
tags:
- { name: route_enhancer, priority: 10 }
route_special_attributes_subscriber:
class: Drupal\Core\EventSubscriber\SpecialAttributesRouteSubscriber
tags:
- { name: event_subscriber }
controller.page:
class: Drupal\Core\Controller\HtmlPageController
arguments: ['@http_kernel']
......
<?php
/**
* @file
* Contains \Drupal\Core\EventSubscriber\SpecialAttributesRouteSubscriber.
*/
namespace Drupal\Core\EventSubscriber;
use Drupal\Component\Utility\String;
use Drupal\Core\Routing\RouteBuildEvent;
use Drupal\Core\Routing\RoutingEvents;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Provides a route subscriber which checks for invalid pattern variables.
*/
class SpecialAttributesRouteSubscriber implements EventSubscriberInterface {
/**
* Checks for invalid pattern variables.
*
* @param \Drupal\Core\Routing\RouteBuildEvent $event
* The event containing the build routes.
*
* @throws \InvalidArgumentException
* Thrown when a reserved variable was used as route variable.
*/
public function onRouteBuilding(RouteBuildEvent $event) {
$special_variables = array(
'_account',
'system_path',
'_maintenance',
'_legacy',
'_authentication_provider',
'_raw_variables',
RouteObjectInterface::ROUTE_OBJECT,
RouteObjectInterface::ROUTE_NAME,
'_content',
'_form',
);
foreach ($event->getRouteCollection()->all() as $route) {
if ($not_allowed_variables = array_intersect($route->compile()->getVariables(), $special_variables)) {
$placeholders = array('@variables' => implode(', ', $not_allowed_variables));
drupal_set_message(String::format('The following variables are reserved names by drupal: @variables', $placeholders));
watchdog('error', 'The following variables are reserved names by drupal: @variables', $placeholders);
return FALSE;
}
}
return TRUE;
}
/**
* {@inheritdoc}
*/
static function getSubscribedEvents() {
$events[RoutingEvents::ALTER][] = 'onRouteBuilding';
return $events;
}
}
<?php
/**
* @file
* Contains \Drupal\Tests\Core\EventSubscriber\SpecialAttributesRouteSubscriberTest.
*/
namespace Drupal\Tests\Core\EventSubscriber {
use Drupal\Core\EventSubscriber\SpecialAttributesRouteSubscriber;
use Drupal\Core\Routing\RouteBuildEvent;
use Drupal\Tests\UnitTestCase;
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* Tests the special attributes route subscriber.
*
* @see \Drupal\Core\EventSubscriber\SpecialAttributesRouteSubscriber
*/
class SpecialAttributesRouteSubscriberTest extends UnitTestCase {
/**
* The tested route subscriber.
*
* @var \Drupal\Core\EventSubscriber\SpecialAttributesRouteSubscriber
*/
protected $specialAttributesRouteSubscriber;
public static function getInfo() {
return array(
'name' => 'Special attributes route subscriber',
'description' => 'Tests the special attributes route subscriber.',
'group' => 'System'
);
}
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->specialAttributesRouteSubscriber = new SpecialAttributesRouteSubscriber();
}
/**
* Provides a list of routes with invalid route variables.
*
* @return array
* An array of invalid routes.
*/
public function providerTestOnRouteBuildingInvalidVariables() {
$routes = array();
$routes[] = array(new Route('/test/{_account}'));
$routes[] = array(new Route('/test/{system_path}'));
$routes[] = array(new Route('/test/{_maintenance}'));
$routes[] = array(new Route('/test/{_legacy}'));
$routes[] = array(new Route('/test/{_authentication_provider}'));
$routes[] = array(new Route('/test/{' . RouteObjectInterface::ROUTE_OBJECT . '}'));
$routes[] = array(new Route('/test/{' . RouteObjectInterface::ROUTE_NAME . '}'));
$routes[] = array(new Route('/test/{_content}'));
$routes[] = array(new Route('/test/{_form}'));
$routes[] = array(new Route('/test/{_raw_variables}'));
return $routes;
}
/**
* Provides a list of routes with valid route variables.
*
* @return array
* An array of valid routes.
*/
public function providerTestOnRouteBuildingValidVariables() {
$routes = array();
$routes[] = array(new Route('/test/{account}'));
$routes[] = array(new Route('/test/{node}'));
$routes[] = array(new Route('/test/{user}'));
$routes[] = array(new Route('/test/{entity_test}'));
return $routes;
}
/**
* Tests the onRouteBuilding method for valid variables.
*
* @param \Symfony\Component\Routing\Route $route
* The route to check.
*
* @dataProvider providerTestOnRouteBuildingValidVariables
*/
public function testOnRouteBuildingValidVariables(Route $route) {
$route_collection = new RouteCollection();
$route_collection->add('test', $route);
$event = new RouteBuildEvent($route_collection, 'test');
$this->assertTrue($this->specialAttributesRouteSubscriber->onRouteBuilding($event));
}
/**
* Tests the onRouteBuilding method for invalid variables.
*
* @param \Symfony\Component\Routing\Route $route
* The route to check.
*
* @dataProvider providerTestOnRouteBuildingInvalidVariables
*/
public function testOnRouteBuildingInvalidVariables(Route $route) {
$route_collection = new RouteCollection();
$route_collection->add('test', $route);
$event = new RouteBuildEvent($route_collection, 'test');
$this->assertFalse($this->specialAttributesRouteSubscriber->onRouteBuilding($event));
}
}
}
namespace {
if (!function_exists('watchdog')) {
function watchdog($type, $message, array $args = NULL) {
}
}
if (!function_exists('drupal_set_message')) {
function drupal_set_message($type = NULL, $message = '') {
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment