From b77c2c40b4a18c547cf1ddad944d4cc406dc8a43 Mon Sep 17 00:00:00 2001 From: JoshyPHP Date: Sun, 13 Sep 2020 19:23:45 +0200 Subject: [PATCH] Replace implicit dependence on ext/iconv in JS escaper polyfill-iconv does not support the UTF-16BE conversion --- src/Extension/EscaperExtension.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Extension/EscaperExtension.php b/src/Extension/EscaperExtension.php index b49c08b92..2be89414d 100644 --- a/src/Extension/EscaperExtension.php +++ b/src/Extension/EscaperExtension.php @@ -282,15 +282,18 @@ function twig_escape_filter(Environment $env, $string, $strategy = 'html', $char return $shortMap[$char]; } - // \uHHHH - $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8'); - $char = strtoupper(bin2hex($char)); - - if (4 >= \strlen($char)) { - return sprintf('\u%04s', $char); + $codepoint = mb_ord($char); + if (0x10000 > $codepoint) { + return sprintf('\u%04X', $codepoint); } - return sprintf('\u%04s\u%04s', substr($char, 0, -4), substr($char, -4)); + // 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) {