ng.'); } $string = \preg_replace_callback('#[^a-zA-Z0-9,\\._]#Su', function ($matches) { $char = $matches[0]; static $shortMap = ['\\' => '\\\\', '/' => '\\/', "\x08" => '\\b', "\f" => '\\f', "\n" => '\\n', "\r" => '\\r', "\t" => '\\t']; if (isset($shortMap[$char])) { return $shortMap[$char]; } $codepoint = \mb_ord($char, 'UTF-8'); if (0x10000 > $codepoint) { return \sprintf('\\u%04X', $codepoint); } // Split characters outside the BMP into surrogate pairs // https://tools.ietf.org/html/rfc2781.html#section-2.1 $u = $codepoint - 0x10000; $high = 0xd800 | $u >> 10; $low = 0xdc00 | $u & 0x3ff; return \sprintf('\\u%04X\\u%04X', $high, $low); }, $string); if ('UTF-8' !== $charset) { $string = \iconv('UTF-8', $charset, $string); } return $string; case 'css': if ('UTF-8' !== $charset) { $string = $this->convertEncoding($string, 'UTF-8', $charset); } if (!\preg_match('//u', $string)) { throw new RuntimeError('The string to escape is not a valid UTF-8 string.'); } $string = \preg_replace_callback('#[^a-zA-Z0-9]#Su', function ($matches) { $char = $matches[0]; return \sprintf('\\%X ', 1 === \strlen($char) ? \ord($char) : \mb_ord($char, 'UTF-8')); }, $string); if ('UTF-8' !== $charset) { $string = \iconv('UTF-8', $charset, $string); } return $string; case 'html_attr': if ('UTF-8' !== $charset) { $string = $this->convertEncoding($string, 'UTF-8', $charset); } if (!\preg_match('//u', $string)) { throw new RuntimeError('The string to escape is not a valid UTF-8 string.'); } $string = \preg_replace_callback('#[^a-zA-Z0-9,\\.\\-_]#Su', function ($matches) { $chr = $matches[0]; $ord = \ord($chr); if ($ord <= 0x1f && "\t" != $chr && "\n" != $chr && "\r" != $chr || $ord >= 0x7f && $ord <= 0x9f) { return '�'; } if (1 === \strlen($chr)) { static $entityMap = [ 34 => '"', 38 => '&', 60 => '<', 62 => '>', ]; if (isset($entityMap[$ord])) { return $entityMap[$ord]; } return \sprintf('&#x%02X;', $ord); } return \sprintf('&#x%04X;', \mb_ord($chr, 'UTF-8')); }, $string); if ('UTF-8' !== $charset) { $string = \iconv('UTF-8', $charset, $string); } return $string; case 'url': return \rawurlencode($string); default: if (\array_key_exists($strategy, $this->escapers)) { return $this->escapers[$strategy]($string, $charset); } $validStrategies = \implode('", "', \array_merge(['html', 'js', 'url', 'css', 'html_attr'], \array_keys($this->escapers))); throw new RuntimeError(\sprintf('Invalid escaping strategy "%s" (valid ones: "%s").', $strategy, $validStrategies)); } } private function convertEncoding(string $string, string $to, string $from) { if (!\function_exists('iconv')) { throw new RuntimeError('Unable to convert encoding: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.'); } return \iconv($from, $to, $string); } }