From 6a377ab0d729120f1db74e72c14fb1a6f85dde88 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Sun, 10 Jul 2022 13:45:50 -0400 Subject: [PATCH 1/4] add unit test with doubly encoded url in URL path --- tests/Router/UrlGeneratorTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/Router/UrlGeneratorTest.php b/tests/Router/UrlGeneratorTest.php index 5ec7a9330..60c57c0d9 100644 --- a/tests/Router/UrlGeneratorTest.php +++ b/tests/Router/UrlGeneratorTest.php @@ -537,4 +537,18 @@ public function testQueryArgsArrayMatchLaravel() ); } } + + 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)) + ); + } } From 564850d6be2574e8ac95d648104fc56d451403e7 Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 13 Jul 2022 06:59:01 -0400 Subject: [PATCH 2/4] only urldecode the query string --- src/Router/UrlGenerator.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Router/UrlGenerator.php b/src/Router/UrlGenerator.php index 74791ef8a..1acbb4e34 100644 --- a/src/Router/UrlGenerator.php +++ b/src/Router/UrlGenerator.php @@ -65,10 +65,18 @@ public static function buildUrl($url, $replace = [], $flags = HTTP_URL_REPLACE, // Parse input if (is_string($url)) { - $url = parse_url(urldecode($url)); + if (str_contains($url, '?')) { + list($uri, $qs) = explode('?', $url); + $url = $uri . '?' . urldecode($qs); + } + $url = parse_url($url); } if (is_string($replace)) { - $replace = parse_url(urldecode($replace)); + if (str_contains($replace, '?')) { + list($uri, $qs) = explode('?', $replace); + $replace = $uri . '?' . urldecode($qs); + } + $replace = parse_url($replace); } // Prepare input data From 22869478c0bf898251dca034fc9d73261579dadb Mon Sep 17 00:00:00 2001 From: Marc Jauvin Date: Wed, 13 Jul 2022 08:59:19 -0400 Subject: [PATCH 3/4] add test for single encoded URL in path --- tests/Router/UrlGeneratorTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/Router/UrlGeneratorTest.php b/tests/Router/UrlGeneratorTest.php index 60c57c0d9..c4e69857e 100644 --- a/tests/Router/UrlGeneratorTest.php +++ b/tests/Router/UrlGeneratorTest.php @@ -538,6 +538,20 @@ 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'; From 0af7ac365e637feb12e155e0ebeb95b0a6d572f5 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Wed, 13 Jul 2022 14:47:06 -0600 Subject: [PATCH 4/4] Centralize logic --- src/Router/UrlGenerator.php | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Router/UrlGenerator.php b/src/Router/UrlGenerator.php index 1acbb4e34..657182d13 100644 --- a/src/Router/UrlGenerator.php +++ b/src/Router/UrlGenerator.php @@ -63,20 +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)) { - if (str_contains($url, '?')) { - list($uri, $qs) = explode('?', $url); - $url = $uri . '?' . urldecode($qs); - } - $url = parse_url($url); + $url = parse_url($decodeQueryParams($url)); } if (is_string($replace)) { - if (str_contains($replace, '?')) { - list($uri, $qs) = explode('?', $replace); - $replace = $uri . '?' . urldecode($qs); - } - $replace = parse_url($replace); + $replace = parse_url($decodeQueryParams($replace)); } // Prepare input data