summaryrefslogtreecommitdiff
path: root/ext/json
diff options
context:
space:
mode:
authorIlia Alshanetsky <iliaa@php.net>2007-04-16 22:31:05 +0000
committerIlia Alshanetsky <iliaa@php.net>2007-04-16 22:31:05 +0000
commit8b245e5aafe1eca2a40fd640c68198fc583762af (patch)
treefbc6755918cb4c423c203997950f68b08144cf7c /ext/json
parent8f845b705bb0ff28947b1585133e7d157805fe2f (diff)
downloadphp-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.c19
-rw-r--r--ext/json/tests/bug41067.phpt23
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