diff options
author | Ilia Alshanetsky <iliaa@php.net> | 2007-04-16 22:31:05 +0000 |
---|---|---|
committer | Ilia Alshanetsky <iliaa@php.net> | 2007-04-16 22:31:05 +0000 |
commit | 8b245e5aafe1eca2a40fd640c68198fc583762af (patch) | |
tree | fbc6755918cb4c423c203997950f68b08144cf7c /ext/json | |
parent | 8f845b705bb0ff28947b1585133e7d157805fe2f (diff) | |
download | php-git-8b245e5aafe1eca2a40fd640c68198fc583762af.tar.gz |
Fixed bug #41067 (json_encode() problem with UTF-16 input).
Diffstat (limited to 'ext/json')
-rw-r--r-- | ext/json/JSON_parser.c | 19 | ||||
-rw-r--r-- | ext/json/tests/bug41067.phpt | 23 |
2 files changed, 42 insertions, 0 deletions
diff --git a/ext/json/JSON_parser.c b/ext/json/JSON_parser.c index 0fbdb1add1..b57d65174e 100644 --- a/ext/json/JSON_parser.c +++ b/ext/json/JSON_parser.c @@ -316,6 +316,25 @@ static void utf16_to_utf8(smart_str *buf, unsigned short utf16) smart_str_appendc(buf, 0xc0 | (utf16 >> 6)); smart_str_appendc(buf, 0x80 | (utf16 & 0x3f)); } + else if ((utf16 & 0xfc00) == 0xdc00 + && buf->len >= 3 + && ((unsigned char) buf->c[buf->len - 3]) == 0xed + && ((unsigned char) buf->c[buf->len - 2] & 0xf0) == 0xa0 + && ((unsigned char) buf->c[buf->len - 1] & 0xc0) == 0x80) + { + /* found surrogate pair */ + unsigned long utf32; + + utf32 = (((buf->c[buf->len - 2] & 0xf) << 16) + | ((buf->c[buf->len - 1] & 0x3f) << 10) + | (utf16 & 0x3ff)) + 0x10000; + buf->len -= 3; + + smart_str_appendc(buf, 0xf0 | (utf32 >> 18)); + smart_str_appendc(buf, 0x80 | ((utf32 >> 12) & 0x3f)); + smart_str_appendc(buf, 0x80 | ((utf32 >> 6) & 0x3f)); + smart_str_appendc(buf, 0x80 | (utf32 & 0x3f)); + } else { smart_str_appendc(buf, 0xe0 | (utf16 >> 12)); diff --git a/ext/json/tests/bug41067.phpt b/ext/json/tests/bug41067.phpt new file mode 100644 index 0000000000..b20e6e1b53 --- /dev/null +++ b/ext/json/tests/bug41067.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #41067 (json_encode() problem with UTF-16 input) +--SKIPIF-- +<?php if (!extension_loaded("json")) print "skip"; ?> +--FILE-- +<?php +$single_barline = "\360\235\204\200"; +$array = array($single_barline); +print bin2hex($single_barline) . "\n"; +// print $single_barline . "\n\n"; +$json = json_encode($array); +print $json . "\n\n"; +$json_decoded = json_decode($json, true); +// print $json_decoded[0] . "\n"; +print bin2hex($json_decoded[0]) . "\n"; +print "END\n"; +?> +--EXPECT-- +f09d8480 +["\ud834\udd00"] + +f09d8480 +END |