diff --git a/src/Router/UrlGenerator.php b/src/Router/UrlGenerator.php index 74791ef8a..657182d13 100644 --- a/src/Router/UrlGenerator.php +++ b/src/Router/UrlGenerator.php @@ -63,12 +63,21 @@ public static function buildUrl($url, $replace = [], $flags = HTTP_URL_REPLACE, | HTTP_URL_STRIP_PASS; } + // Decode query parameters before parsing the URL + $decodeQueryParams = function (string $url): string { + if (Str::contains($url, '?')) { + list($urlWithoutQuery, $queryArgs) = explode('?', $url, 2); + $url = $urlWithoutQuery . '?' . urldecode($queryArgs); + } + return $url; + }; + // Parse input if (is_string($url)) { - $url = parse_url(urldecode($url)); + $url = parse_url($decodeQueryParams($url)); } if (is_string($replace)) { - $replace = parse_url(urldecode($replace)); + $replace = parse_url($decodeQueryParams($replace)); } // Prepare input data diff --git a/tests/Router/UrlGeneratorTest.php b/tests/Router/UrlGeneratorTest.php index 5ec7a9330..c4e69857e 100644 --- a/tests/Router/UrlGeneratorTest.php +++ b/tests/Router/UrlGeneratorTest.php @@ -537,4 +537,32 @@ public function testQueryArgsArrayMatchLaravel() ); } } + + public function testEncodedUrlInPathMatchLaravel() + { + $urlInPath = 'https://testUrlInPath/path?k1=v1&k2'; + $url = 'https://testdomain/' . rawurlencode($urlInPath); + + $generator = new \Winter\Storm\Router\UrlGenerator(new RouteCollection, Request::create($url)); + $baseGenerator = new \Illuminate\Routing\UrlGenerator(new RouteCollection, Request::create($url)); + + $this->assertEquals( + urldecode($baseGenerator->to($url)), + urldecode($generator->to($url)) + ); + } + + public function testDoublyEncodedUrlInPathMatchLaravel() + { + $urlInPath = 'https://testUrlInPath/path?k1=v1&k2'; + $url = 'https://testdomain/' . rawurlencode(rawurlencode($urlInPath)); + + $generator = new \Winter\Storm\Router\UrlGenerator(new RouteCollection, Request::create($url)); + $baseGenerator = new \Illuminate\Routing\UrlGenerator(new RouteCollection, Request::create($url)); + + $this->assertEquals( + urldecode($baseGenerator->to($url)), + urldecode($generator->to($url)) + ); + } }