From 5dad522a9932d4d168881202485178b17744fea1 Mon Sep 17 00:00:00 2001 From: Jonas De Keukelaere Date: Thu, 4 Jun 2026 10:39:03 +0100 Subject: [PATCH 1/2] Fix redirect encoding --- src/Backend/Modules/Pages/Engine/Model.php | 26 ++++++++++--------- .../Modules/Pages/Tests/Model/ModelTest.php | 4 +++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Backend/Modules/Pages/Engine/Model.php b/src/Backend/Modules/Pages/Engine/Model.php index 49a3c64339..c500f3a4c9 100644 --- a/src/Backend/Modules/Pages/Engine/Model.php +++ b/src/Backend/Modules/Pages/Engine/Model.php @@ -1546,20 +1546,22 @@ 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); - } - unset($urlChunk); - $redirectUrl = $matches[1] . '://' . $domain . '/' . implode('/', $urlChunks); + $parsedUrl = parse_url($redirectUrl); + + // Encode quotes in url path + if (isset($parsedUrl['path'])) { + $parsedUrl['path'] = str_replace(['"', '\''], ['%22', '%27'], $parsedUrl['path']); + } + + $url = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . $parsedUrl['path']; + if (isset($parsedUrl['query'])) { + $url .= '?' . $parsedUrl['query']; + } + if (isset($parsedUrl['fragment'])) { + $url .= '#' . $parsedUrl['fragment']; } - return $redirectUrl; + 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..4f80435f81 100644 --- a/src/Backend/Modules/Pages/Tests/Model/ModelTest.php +++ b/src/Backend/Modules/Pages/Tests/Model/ModelTest.php @@ -25,5 +25,9 @@ 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') + ); } } From 287fc1be1f8e37217d332d47c8e5c0c12cd9568d Mon Sep 17 00:00:00 2001 From: Jonas De Keukelaere Date: Thu, 4 Jun 2026 12:42:51 +0100 Subject: [PATCH 2/2] Fix rebuilding url after encoding path --- src/Backend/Modules/Pages/Engine/Model.php | 33 ++++++++++++++++++- .../Modules/Pages/Tests/Model/ModelTest.php | 8 +++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/Backend/Modules/Pages/Engine/Model.php b/src/Backend/Modules/Pages/Engine/Model.php index c500f3a4c9..974bba03bc 100644 --- a/src/Backend/Modules/Pages/Engine/Model.php +++ b/src/Backend/Modules/Pages/Engine/Model.php @@ -1548,12 +1548,43 @@ public static function getEncodedRedirectUrl(string $redirectUrl): string { $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']); } - $url = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . $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']; + } + } + + $url .= $parsedUrl['path'] ?? ''; + if (isset($parsedUrl['query'])) { $url .= '?' . $parsedUrl['query']; } diff --git a/src/Backend/Modules/Pages/Tests/Model/ModelTest.php b/src/Backend/Modules/Pages/Tests/Model/ModelTest.php index 4f80435f81..5c9fd66d4d 100644 --- a/src/Backend/Modules/Pages/Tests/Model/ModelTest.php +++ b/src/Backend/Modules/Pages/Tests/Model/ModelTest.php @@ -29,5 +29,13 @@ public function testUrlIsEncoded(): void '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') + ); } }