From 24a0291b1b9fd483976634ea168fe272e54df101 Mon Sep 17 00:00:00 2001 From: Lazizbek Ergashev Date: Sun, 12 Jul 2026 17:00:30 +0500 Subject: [PATCH 1/3] Fix malformed URLs with duplicate leading slashes resolving to home page --- src/Facades/Endpoint/Path.php | 3 +++ src/Facades/Endpoint/URL.php | 3 +++ tests/Data/DataRepositoryTest.php | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/Facades/Endpoint/Path.php b/src/Facades/Endpoint/Path.php index d034e537937..27340f17fd6 100644 --- a/src/Facades/Endpoint/Path.php +++ b/src/Facades/Endpoint/Path.php @@ -196,6 +196,9 @@ public function tidy($path) // PHP is capable of understanding Windows paths that use forward slashes. $path = str_replace('\\', '/', (string) $path); + // Normalize multiple leading slashes to a single slash (e.g., ////path => /path). + $path = preg_replace('#^/+#', '/', $path); + // Remove occurrences of "//" in a $path (except when part of a protocol). return preg_replace('#(^|[^:])//+#', '\\1/', (string) $path); } diff --git a/src/Facades/Endpoint/URL.php b/src/Facades/Endpoint/URL.php index 86f9affeefe..4eb7182c91c 100644 --- a/src/Facades/Endpoint/URL.php +++ b/src/Facades/Endpoint/URL.php @@ -174,6 +174,9 @@ public function removeSiteUrl(?string $url): string */ public function makeRelative(?string $url): string { + // Normalize duplicate leading slashes before parsing to avoid protocol-relative URL interpretation. + $url = preg_replace('#^/+#', '/', (string) $url); + $parsed = parse_url($url); $url = $parsed['path'] ?? '/'; diff --git a/tests/Data/DataRepositoryTest.php b/tests/Data/DataRepositoryTest.php index 6ba7f3f1e79..5af4da0ef85 100644 --- a/tests/Data/DataRepositoryTest.php +++ b/tests/Data/DataRepositoryTest.php @@ -156,6 +156,8 @@ public static function findByRequestUrlProvider() 'missing with slash' => ['http://localhost/unknown/', null], 'missing with query' => ['http://localhost/unknown?a=b', null], 'missing with query and slash' => ['http://localhost/unknown/?a=b', null], + 'missing with double leading slashes' => ['http://localhost//unknown', null], + 'missing with multiple leading slashes' => ['http://localhost////unknown', null], ]; } From 19860c46294e3b5701b38893d15304733a069fcb Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Mon, 13 Jul 2026 15:35:35 -0400 Subject: [PATCH 2/3] Remove redundant leading-slash normalization in Path::tidy() The following line already collapses any run of leading slashes to a single slash, making this addition a no-op. --- src/Facades/Endpoint/Path.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Facades/Endpoint/Path.php b/src/Facades/Endpoint/Path.php index 27340f17fd6..d034e537937 100644 --- a/src/Facades/Endpoint/Path.php +++ b/src/Facades/Endpoint/Path.php @@ -196,9 +196,6 @@ public function tidy($path) // PHP is capable of understanding Windows paths that use forward slashes. $path = str_replace('\\', '/', (string) $path); - // Normalize multiple leading slashes to a single slash (e.g., ////path => /path). - $path = preg_replace('#^/+#', '/', $path); - // Remove occurrences of "//" in a $path (except when part of a protocol). return preg_replace('#(^|[^:])//+#', '\\1/', (string) $path); } From 907c4c6577ac213cfba3540e43fce47e6a0b7914 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Mon, 13 Jul 2026 15:35:38 -0400 Subject: [PATCH 3/3] Move duplicate-leading-slash test cases to UrlTest's relativeProvider Tests URL::makeRelative() directly instead of only through the DataRepository integration test. --- tests/Data/DataRepositoryTest.php | 2 -- tests/Facades/UrlTest.php | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Data/DataRepositoryTest.php b/tests/Data/DataRepositoryTest.php index 5af4da0ef85..6ba7f3f1e79 100644 --- a/tests/Data/DataRepositoryTest.php +++ b/tests/Data/DataRepositoryTest.php @@ -156,8 +156,6 @@ public static function findByRequestUrlProvider() 'missing with slash' => ['http://localhost/unknown/', null], 'missing with query' => ['http://localhost/unknown?a=b', null], 'missing with query and slash' => ['http://localhost/unknown/?a=b', null], - 'missing with double leading slashes' => ['http://localhost//unknown', null], - 'missing with multiple leading slashes' => ['http://localhost////unknown', null], ]; } diff --git a/tests/Facades/UrlTest.php b/tests/Facades/UrlTest.php index 21dcee85b5d..8986f593271 100644 --- a/tests/Facades/UrlTest.php +++ b/tests/Facades/UrlTest.php @@ -642,6 +642,8 @@ public static function relativeProvider() 'already relative nested route without trailing slash' => ['/foo/page', '/foo/page'], 'already relative nested route with trailing slash' => ['/foo/page/', '/foo/page'], 'already relative nested route without leading slash' => ['foo/page', '/foo/page'], + 'duplicate leading slashes' => ['//page', '/page'], + 'multiple duplicate leading slashes' => ['////page', '/page'], 'homepage without trailing slash and query param' => ['http://example.com?bar=baz', '/?bar=baz'], 'homepage with trailing slash and query param' => ['http://example.com/?bar=baz', '/?bar=baz'],