diff --git a/src/Backend/Modules/Pages/Engine/Model.php b/src/Backend/Modules/Pages/Engine/Model.php index 49a3c64339..974bba03bc 100644 --- a/src/Backend/Modules/Pages/Engine/Model.php +++ b/src/Backend/Modules/Pages/Engine/Model.php @@ -1546,20 +1546,53 @@ public static function updatePagesTemplates(int $oldTemplateId, int $newTemplate public static function getEncodedRedirectUrl(string $redirectUrl): string { - preg_match('!(http[s]?)://(.*)!i', $redirectUrl, $matches); - $urlChunks = explode('/', $matches[2]); - /** @phpstan-ignore-next-line */ - if (!empty($urlChunks)) { - // skip domain name - $domain = array_shift($urlChunks); - foreach ($urlChunks as &$urlChunk) { - $urlChunk = rawurlencode($urlChunk); + $parsedUrl = parse_url($redirectUrl); + + if ($parsedUrl === false) { + return $redirectUrl; + } + + // Encode quotes in url path + if (isset($parsedUrl['path'])) { + $parsedUrl['path'] = str_replace(['"', '\''], ['%22', '%27'], $parsedUrl['path']); + } + + // Rebuild URL + $url = ''; + + if (isset($parsedUrl['scheme'])) { + $url .= $parsedUrl['scheme']; + $url .= isset($parsedUrl['host']) ? '://' : ':'; + } + + if (isset($parsedUrl['host'])) { + if (isset($parsedUrl['user'])) { + $url .= $parsedUrl['user']; + + if (isset($parsedUrl['pass'])) { + $url .= ':' . $parsedUrl['pass']; + } + + $url .= '@'; + } + + $url .= $parsedUrl['host']; + + if (isset($parsedUrl['port'])) { + $url .= ':' . $parsedUrl['port']; } - unset($urlChunk); - $redirectUrl = $matches[1] . '://' . $domain . '/' . implode('/', $urlChunks); } - return $redirectUrl; + $url .= $parsedUrl['path'] ?? ''; + + if (isset($parsedUrl['query'])) { + $url .= '?' . $parsedUrl['query']; + } + if (isset($parsedUrl['fragment'])) { + $url .= '#' . $parsedUrl['fragment']; + } + + return $url; } private static function getNewParent(int $droppedOnPageId, string $typeOfDrop, array $droppedOnPage): int diff --git a/src/Backend/Modules/Pages/Tests/Model/ModelTest.php b/src/Backend/Modules/Pages/Tests/Model/ModelTest.php index ddc7abd237..5c9fd66d4d 100644 --- a/src/Backend/Modules/Pages/Tests/Model/ModelTest.php +++ b/src/Backend/Modules/Pages/Tests/Model/ModelTest.php @@ -25,5 +25,17 @@ public function testUrlIsEncoded(): void 'http://cédé.be/Quote%22HelloWorld%22', Model::getEncodedRedirectUrl('http://cédé.be/Quote"HelloWorld"') ); + self::assertEquals( + 'http://example.com/test#événements', + Model::getEncodedRedirectUrl('http://example.com/test#événements') + ); + self::assertEquals( + 'https://user:pass@example.com:8443/foo%22bar?x=1#frag', + Model::getEncodedRedirectUrl('https://user:pass@example.com:8443/foo"bar?x=1#frag') + ); + self::assertEquals( + 'https://example.com?foo=bar#frag', + Model::getEncodedRedirectUrl('https://example.com?foo=bar#frag') + ); } }