diff --git a/src/Latte/Runtime/Filters.php b/src/Latte/Runtime/Filters.php index 503e3067f..90a727188 100644 --- a/src/Latte/Runtime/Filters.php +++ b/src/Latte/Runtime/Filters.php @@ -228,11 +228,11 @@ public static function convertHtmlToText(string $s): string /** * Sanitizes string for use inside href attribute. */ - public static function safeUrl(string|HtmlStringable $s): string + public static function safeUrl(string|\Stringable $s): string { - if ($s instanceof HtmlStringable) { - $s = self::convertHtmlToText((string) $s); - } + $s = $s instanceof HtmlStringable + ? self::convertHtmlToText((string) $s) + : (string) $s; return preg_match('~^(?:(?:https?|ftp)://[^@]+(?:/.*)?|(?:mailto|tel|sms):.+|[/?#].*|[^:]+)$~Di', $s) ? $s : ''; } diff --git a/tests/common/Safe.url.phpt b/tests/common/Safe.url.phpt index 95228c091..ff7a3ebe4 100644 --- a/tests/common/Safe.url.phpt +++ b/tests/common/Safe.url.phpt @@ -84,3 +84,22 @@ Assert::match( '', $latte->renderToString('{capture $url}https://nette.org?a=1&b={=""}{/capture}'), ); + +Assert::match( + '', + $latte->renderToString('{capture $url}javascript:foo{/capture}'), +); + +// accepts Stringable +Assert::match( + '', + $latte->renderToString( + '', + ['url' => new class { + public function __toString() + { + return ''; + } + }], + ), +);