diff --git a/app/bundles/CoreBundle/Helper/UrlHelper.php b/app/bundles/CoreBundle/Helper/UrlHelper.php index 7af2b87e623..acc0dfb45a2 100644 --- a/app/bundles/CoreBundle/Helper/UrlHelper.php +++ b/app/bundles/CoreBundle/Helper/UrlHelper.php @@ -324,4 +324,21 @@ private static function removeTrailingNonAlphaNumeric($string) return $string; } + + /** + * This method return true with special characters in URL, for example https://domain.tld/é.pdf + * filter_var($url, FILTER_VALIDATE_URL) allow only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed]. + * + * @param string $url + * + * @return bool + */ + public static function isValidUrl($url) + { + $path = parse_url($url, PHP_URL_PATH); + $encodedPath = array_map('urlencode', explode('/', $path)); + $url = str_replace($path, implode('/', $encodedPath), $url); + + return (bool) filter_var($url, FILTER_VALIDATE_URL); + } } diff --git a/app/bundles/CoreBundle/Tests/Unit/Helper/UrlHelperTest.php b/app/bundles/CoreBundle/Tests/Unit/Helper/UrlHelperTest.php index 4fd71f2f5c2..1920cac975b 100644 --- a/app/bundles/CoreBundle/Tests/Unit/Helper/UrlHelperTest.php +++ b/app/bundles/CoreBundle/Tests/Unit/Helper/UrlHelperTest.php @@ -181,4 +181,12 @@ public function testGetUrlsFromPlaintextWithSymbols() ) ); } + + public function testUrlValid() + { + $this->assertTrue(UrlHelper::isValidUrl('https://domain.tld/e')); + $this->assertTrue(UrlHelper::isValidUrl('https://domain.tld/é')); + $this->assertFalse(UrlHelper::isValidUrl('notvalidurl')); + $this->assertFalse(UrlHelper::isValidUrl('notvalidurlé')); + } } diff --git a/app/bundles/PageBundle/Controller/PublicController.php b/app/bundles/PageBundle/Controller/PublicController.php index cce560db39f..49501ab7337 100644 --- a/app/bundles/PageBundle/Controller/PublicController.php +++ b/app/bundles/PageBundle/Controller/PublicController.php @@ -491,7 +491,7 @@ public function redirectAction($redirectId) $url = UrlHelper::sanitizeAbsoluteUrl($url); - if (false === filter_var($url, FILTER_VALIDATE_URL)) { + if (!UrlHelper::isValidUrl($url)) { throw $this->createNotFoundException($this->translator->trans('mautic.core.url.error.404', ['%url%' => $url])); }