From 3116614f70691958351b1bcfa1f5db0b85a361cd Mon Sep 17 00:00:00 2001 From: Dave Long <dave@longwaveconsulting.com> Date: Tue, 10 Dec 2024 21:30:03 +0000 Subject: [PATCH] Issue #3490710 by mfb, catch, spokje: Catch potential exception when calling Request::create() in PathBasedBreadcrumbBuilder (cherry picked from commit c6143563c318afd4864e60b31a6642afa5bf177a) --- .../system/src/PathBasedBreadcrumbBuilder.php | 8 ++++++- .../PathBasedBreadcrumbBuilderTest.php | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/core/modules/system/src/PathBasedBreadcrumbBuilder.php b/core/modules/system/src/PathBasedBreadcrumbBuilder.php index 26c3066581df..e6b657196f23 100644 --- a/core/modules/system/src/PathBasedBreadcrumbBuilder.php +++ b/core/modules/system/src/PathBasedBreadcrumbBuilder.php @@ -20,6 +20,7 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; +use Symfony\Component\HttpFoundation\Exception\BadRequestException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -211,7 +212,12 @@ protected function getRequestForPath($path, array $exclude) { if (!empty($exclude[$path])) { return NULL; } - $request = Request::create($path); + try { + $request = Request::create($path); + } + catch (BadRequestException) { + return NULL; + } // Performance optimization: set a short accept header to reduce overhead in // AcceptHeaderMatcher when matching the request. $request->headers->set('Accept', 'text/html'); diff --git a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php index fed64ed349d1..d33dd55fa280 100644 --- a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php +++ b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php @@ -336,6 +336,28 @@ public function testBuildWithNonProcessedPath(): void { $this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge()); } + /** + * Tests the build method with an invalid path. + * + * @covers ::build + * @covers ::getRequestForPath + */ + public function testBuildWithInvalidPath(): void { + // The parse_url() function returns FALSE for '/:123/foo' so the + // Request::create() method therefore considers it to be an invalid URI. + $this->context->expects($this->once()) + ->method('getPathInfo') + ->willReturn('/:123/foo/bar'); + + $breadcrumb = $this->builder->build($this->createMock('Drupal\Core\Routing\RouteMatchInterface')); + + // No path matched, though at least the frontpage is displayed. + $this->assertEquals([0 => new Link('Home', new Url('<front>'))], $breadcrumb->getLinks()); + $this->assertEqualsCanonicalizing(['url.path.is_front', 'url.path.parent'], $breadcrumb->getCacheContexts()); + $this->assertEqualsCanonicalizing([], $breadcrumb->getCacheTags()); + $this->assertEquals(Cache::PERMANENT, $breadcrumb->getCacheMaxAge()); + } + /** * Tests the applied method. * -- GitLab