1
0
Fork 0

Make surrogate sequences in JSON work on PHP 5.3

Fixes #7510
pull/7552/head^2
Alexander Kurilo 2018-08-02 23:47:14 +03:00 committed by Jordi Boggiano
parent 1e6ceea0f9
commit 5a22a4f1f3
2 changed files with 21 additions and 0 deletions

View File

@ -69,6 +69,13 @@ class JsonFormatter
$l = strlen($match[1]); $l = strlen($match[1]);
if ($l % 2) { 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( return str_repeat('\\', $l - 1) . mb_convert_encoding(
pack('H*', $match[2]), pack('H*', $match[2]),
'UTF-8', 'UTF-8',

View File

@ -33,6 +33,20 @@ class JsonFormatterTest extends TestCase
$this->assertEquals($expected, $this->getCharacterCodes($encodedData)); $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 * Convert string to character codes split by a plus sign
* @param string $string * @param string $string