diff -u b/core/lib/Drupal/Core/Routing/PathMatcher.php b/core/lib/Drupal/Core/Routing/PathMatcher.php --- b/core/lib/Drupal/Core/Routing/PathMatcher.php +++ b/core/lib/Drupal/Core/Routing/PathMatcher.php @@ -56,7 +56,21 @@ */ public function matchRequestPartial(Request $request) { - $path = '/' . $request->attributes->get('system_path'); + // The 'system_path' has language prefix stripped and path alias resolved, + // whereas getPathInfo() returns the requested path. In Drupal, the request + // always contains a system_path attribute, but this component may get + // adopted by non-Drupal projects. Some unit tests also skip initializing + // 'system_path'. + // @todo Consider abstracting this to a separate object. + if ($request->attributes->has('system_path')) { + // system_path never has leading or trailing slashes. + $path = '/' . $request->attributes->get('system_path'); + } + else { + // getPathInfo() always has leading slash, and might or might not have a + // trailing slash. + $path = rtrim($request->getPathInfo(), '/'); + } $parts = array_slice(array_filter(explode('/', $path)), 0, MatcherDumper::MAX_PARTS); diff -u b/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php --- b/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Routing/PathMatcherTest.php @@ -88,7 +88,6 @@ $path = '/path/one'; $request = Request::create($path, 'GET'); - $request->attributes->set('system_path', trim($path, '/')); $routes = $matcher->matchRequestPartial($request); @@ -113,7 +112,6 @@ $path = '/path/1/one'; $request = Request::create($path, 'GET'); - $request->attributes->set('system_path', trim($path, '/')); $routes = $matcher->matchRequestPartial($request); @@ -143,7 +141,6 @@ $path = '/path/1/one/'; $request = Request::create($path, 'GET'); - $request->attributes->set('system_path', trim($path, '/')); $routes = $matcher->matchRequestPartial($request); @@ -178,7 +175,6 @@ $path = '/some/path'; $request = Request::create($path, 'GET'); - $request->attributes->set('system_path', trim($path, '/')); try { $routes = $matcher->matchRequestPartial($request); @@ -219,7 +215,6 @@ $path = '/some/path'; $request = Request::create($path, 'GET'); - $request->attributes->set('system_path', trim($path, '/')); try { $routes = $matcher->matchRequestPartial($request); @@ -260,7 +255,6 @@ $path = '/some/path/here'; $request = Request::create($path, 'GET'); - $request->attributes->set('system_path', trim($path, '/')); try { $routes = $matcher->matchRequestPartial($request); @@ -294,7 +288,6 @@ $path = '/no/such/path'; $request = Request::create($path, 'GET'); - $request->attributes->set('system_path', trim($path, '/')); try { $routes = $matcher->matchRequestPartial($request); @@ -308,2 +301,25 @@ + /** + * Confirms that system_path attribute overrides request path. + */ + function testSystemPathMatch() { + $connection = Database::getConnection(); + $matcher = new PathMatcher($connection, 'test_routes'); + + $this->fixtures->createTables($connection); + + $dumper = new MatcherDumper($connection, 'test_routes'); + $dumper->addRoutes($this->fixtures->sampleRouteCollection()); + $dumper->dump(); + + $request = Request::create('/path/one', 'GET'); + $request->attributes->set('system_path', 'path/two'); + + $routes = $matcher->matchRequestPartial($request); + + foreach ($routes as $route) { + $this->assertEqual($route->getPattern(), '/path/two', 'Found path has correct pattern'); + } + } + } diff -u b/core/modules/user/lib/Drupal/user/UserRouteController.php b/core/modules/user/lib/Drupal/user/UserRouteController.php --- b/core/modules/user/lib/Drupal/user/UserRouteController.php +++ b/core/modules/user/lib/Drupal/user/UserRouteController.php @@ -7,12 +7,13 @@ namespace Drupal\user; +use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; /** * Returns responses for User module routes. */ -class UserRouteController { +class UserRouteController extends ContainerAware { /** * Returns the user registration form.