', '[', ']', '*', '_'], ['&', '\', '"', '<', '>', '[', ']', '*', '_'], $text ); return Backticks::escapeText($text); } public static function escapeDestination(string $url): string { $characters = self::hasBalancedParentheses($url) ? '' : '()'; $url = \preg_replace_callback('/[\x00-\x20\x7F"<>\\\\`\[\]*' . $characters . ']/', static function (array $matches): string { return '%' . \strtoupper(\bin2hex($matches[0])); }, $url); \assert($url !== null); return $url; } private static function hasBalancedParentheses(string $url): bool { $depth = 0; foreach (\str_split(\preg_replace('/[^()]/', '', $url) ?? $url) as $character) { $depth += $character === '(' ? 1 : ($character === ')' ? -1 : 0); if ($depth < 0 || $depth > self::MAX_PARENTHESES_DEPTH) { return false; } } return $depth === 0; } }