Commit d9a92c36 authored by catch's avatar catch

Issue #2616498 by neclimdul, dawehner, Mixologic:...

Issue #2616498 by neclimdul, dawehner, Mixologic: Drupal\Core\Routing\RouteProvider::getCandidateOutlines() does an illegal shift when config is empty
parent 3693ba75
......@@ -10,6 +10,7 @@
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Processes the inbound path by resolving it to the front page if empty.
......@@ -41,6 +42,11 @@ public function __construct(ConfigFactoryInterface $config) {
public function processInbound($path, Request $request) {
if ($path === '/') {
$path = $this->config->get('system.site')->get('page.front');
if (empty($path)) {
// We have to return a valid path but / won't be routable and config
// might be broken so stop execution.
throw new NotFoundHttpException();
}
}
return $path;
}
......
......@@ -257,7 +257,7 @@ protected function getCandidateOutlines(array $parts) {
if ($number_parts == 1) {
$masks = array(1);
}
elseif ($number_parts <= 3) {
elseif ($number_parts <= 3 && $number_parts > 0) {
// Optimization - don't query the state system for short paths. This also
// insulates against the state entry for masks going missing for common
// user-facing paths since we generate all values without checking state.
......@@ -272,7 +272,6 @@ protected function getCandidateOutlines(array $parts) {
$masks = (array) $this->state->get('routing.menu_masks.' . $this->tableName, array());
}
// Only examine patterns that actually exist as router items (the masks).
foreach ($masks as $i) {
if ($i > $end) {
......
......@@ -133,6 +133,15 @@ public function testCandidateOutlines() {
$this->assertTrue(array_key_exists('/node', $candidates), 'Seventh candidate found.');
}
/**
* Don't fail when given an empty path.
*/
public function testEmptyPathCandidatesOutlines() {
$provider = new TestRouteProvider(Database::getConnection(), $this->state, $this->currentPath, $this->cache, $this->pathProcessor, $this->cacheTagsInvalidator, 'test_routes');
$candidates = $provider->getCandidateOutlines([]);
$this->assertEqual(count($candidates), 0, 'Empty parts should return no candidates.');
}
/**
* Confirms that we can find routes with the exact incoming path.
*/
......
<?php
/**
* @file
* Contains \Drupal\Tests\Core\PathProcess\PathProcessorFrontTest
*/
namespace Drupal\Tests\Core\PathProcessor;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\PathProcessor\PathProcessorFront;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\HttpFoundation\Request;
/**
* Test front page path processing.
*
* @group PathProcessor
* @coversDefaultClass \Drupal\Core\PathProcessor\PathProcessorFront
*/
class PathProcessorFrontTest extends UnitTestCase {
/**
* Test basic inbound processing functionality.
*
* @covers ::processInbound
* @dataProvider providerProcessInbound
*/
public function testProcessInbound($path, $expected) {
$config_factory = $this->prophesize(ConfigFactoryInterface::class);
$config = $this->prophesize(ImmutableConfig::class);
$config_factory->get('system.site')
->willReturn($config->reveal());
$config->get('page.front')
->willReturn('/node');
$processor = new PathProcessorFront($config_factory->reveal());
$this->assertEquals($expected, $processor->processInbound($path, new Request()));
}
/**
* Inbound paths and expected results.
*/
public function providerProcessInbound() {
return [
['/', '/node'],
['/user', '/user'],
];
}
/**
* Test inbound failure with broken config.
*
* @covers ::processInbound
* @expectedException \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function testProcessInboundBadConfig() {
$config_factory = $this->prophesize(ConfigFactoryInterface::class);
$config = $this->prophesize(ImmutableConfig::class);
$config_factory->get('system.site')
->willReturn($config->reveal());
$config->get('page.front')
->willReturn('');
$processor = new PathProcessorFront($config_factory->reveal());
$processor->processInbound('/', new Request());
}
/**
* Test basic outbound processing functionality.
*
* @covers ::processOutbound
* @dataProvider providerProcessOutbound
*/
public function testProcessOutbound($path, $expected) {
$config_factory = $this->prophesize(ConfigFactoryInterface::class);
$processor = new PathProcessorFront($config_factory->reveal());
$this->assertEquals($expected, $processor->processOutbound($path));
}
/**
* Outbound paths and expected results.
*/
public function providerProcessOutbound() {
return [
['/<front>', '/'],
['<front>', '<front>'],
['/user', '/user'],
];
}
}
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