From 252448a0063a83354642cf7face1b2188cb4655d Mon Sep 17 00:00:00 2001
From: Lee Rowlands <lee.rowlands@previousnext.com.au>
Date: Wed, 27 Nov 2024 16:04:08 +1000
Subject: [PATCH] Issue #3489329 by mfb, casey: symfony/http-foundation commit
 32310ff breaks PathValidator

(cherry picked from commit 90ab4e3da14e7a4a0d73ee6542ac4b7dd15a7630)
---
 core/lib/Drupal/Core/Path/PathValidator.php      | 11 ++++++++++-
 .../Drupal/Tests/Core/Path/PathValidatorTest.php | 16 ++++++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/core/lib/Drupal/Core/Path/PathValidator.php b/core/lib/Drupal/Core/Path/PathValidator.php
index c132210ca636..978b672cca53 100644
--- a/core/lib/Drupal/Core/Path/PathValidator.php
+++ b/core/lib/Drupal/Core/Path/PathValidator.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
 use Drupal\Core\Routing\RouteObjectInterface;
+use Symfony\Component\HttpFoundation\Exception\BadRequestException;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Symfony\Component\Routing\Exception\MethodNotAllowedException;
@@ -118,7 +119,12 @@ protected function getUrl($path, $access_check) {
       return Url::fromUri($path);
     }
 
-    $request = Request::create('/' . $path);
+    try {
+      $request = Request::create('/' . $path);
+    }
+    catch (BadRequestException) {
+      return FALSE;
+    }
     $attributes = $this->getPathAttributes($path, $request, $access_check);
 
     if (!$attributes) {
@@ -172,6 +178,9 @@ protected function getPathAttributes($path, Request $request, $access_check) {
     catch (MethodNotAllowedException $e) {
       $result = FALSE;
     }
+    catch (BadRequestException) {
+      $result = FALSE;
+    }
 
     $router->setContext($initial_request_context);
     return $result;
diff --git a/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php b/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php
index b7b25b5f85dc..1f80c6f6cd6a 100644
--- a/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php
+++ b/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php
@@ -444,4 +444,20 @@ public function testGetUrlIfValidWithoutAccessCheck(): void {
     $this->assertEquals(['key' => 'value'], $url->getRouteParameters());
   }
 
+  /**
+   * Tests the getUrlIfValidWithoutAccessCheck() method with an invalid path.
+   *
+   * @covers ::getUrlIfValidWithoutAccessCheck
+   * @covers ::getUrl
+   */
+  public function testGetUrlIfValidWithoutAccessCheckWithInvalidPath(): void {
+    // URLs must not start nor end with ASCII control characters or spaces.
+    $this->assertFalse($this->pathValidator->getUrlIfValidWithoutAccessCheck('foo '));
+    // Also check URL-encoded variant.
+    $this->pathProcessor->expects($this->once())
+      ->method('processInbound')
+      ->willReturnArgument(0);
+    $this->assertFalse($this->pathValidator->getUrlIfValidWithoutAccessCheck('foo%20'));
+  }
+
 }
-- 
GitLab