Просмотр исходного кода

Make surrogate sequences in JSON work on PHP 5.3

Fixes #7510
Alexander Kurilo 6 лет назад
Родитель
Сommit
5a22a4f1f3

+ 7 - 0
src/Composer/Json/JsonFormatter.php

@@ -69,6 +69,13 @@ class JsonFormatter
                         $l = strlen($match[1]);
 
                         if ($l % 2) {
+                            $code = hexdec($match[2]);
+                            // 0xD800..0xDFFF denotes UTF-16 surrogate pair which won't be unescaped
+                            // see https://github.com/composer/composer/issues/7510
+                            if (0xD800 <= $code && 0xDFFF >= $code) {
+                                return $match[0];
+                            }
+
                             return str_repeat('\\', $l - 1) . mb_convert_encoding(
                                 pack('H*', $match[2]),
                                 'UTF-8',

+ 14 - 0
tests/Composer/Test/Json/JsonFormatterTest.php

@@ -33,6 +33,20 @@ class JsonFormatterTest extends TestCase
         $this->assertEquals($expected, $this->getCharacterCodes($encodedData));
     }
 
+    /**
+     * Surrogate pairs are intentionally skipped and not unescaped
+     * https://github.com/composer/composer/issues/7510
+     */
+    public function testUtf16SurrogatePair()
+    {
+        if (!extension_loaded('mbstring')) {
+            $this->markTestSkipped('Test requires the mbstring extension');
+        }
+
+        $escaped = '"\ud83d\ude00"';
+        $this->assertEquals($escaped, JsonFormatter::format($escaped, true, true));
+    }
+
     /**
      * Convert string to character codes split by a plus sign
      * @param  string $string