summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/json/json.c10
-rw-r--r--ext/json/tests/bug43941.phpt21
-rw-r--r--ext/json/utf8_to_utf16.c2
3 files changed, 30 insertions, 3 deletions
diff --git a/ext/json/json.c b/ext/json/json.c
index ddfbbe5d26..90e5955c09 100644
--- a/ext/json/json.c
+++ b/ext/json/json.c
@@ -269,8 +269,14 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options) /*
{
efree(utf16);
}
-
- smart_str_appendl(buf, "\"\"", 2);
+ if(len < 0) {
+ if(!PG(display_errors)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid UTF-8 sequence in argument");
+ }
+ smart_str_appendl(buf, "null", 4);
+ } else {
+ smart_str_appendl(buf, "\"\"", 2);
+ }
return;
}
diff --git a/ext/json/tests/bug43941.phpt b/ext/json/tests/bug43941.phpt
new file mode 100644
index 0000000000..0f86d1dfad
--- /dev/null
+++ b/ext/json/tests/bug43941.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #43941 (json_encode() invalid UTF-8)
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+var_dump(json_encode("abc"));
+var_dump(json_encode("ab\xE0"));
+var_dump(json_encode("ab\xE0c"));
+var_dump(json_encode(array("ab\xE0", "ab\xE0c", "abc")));
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(5) ""abc""
+string(4) "null"
+string(4) "null"
+string(17) "[null,null,"abc"]"
+Done
+
diff --git a/ext/json/utf8_to_utf16.c b/ext/json/utf8_to_utf16.c
index bc2d6f36d6..42ea9e5d8e 100644
--- a/ext/json/utf8_to_utf16.c
+++ b/ext/json/utf8_to_utf16.c
@@ -40,7 +40,7 @@ utf8_to_utf16(unsigned short w[], char p[], int length)
for (;;) {
c = utf8_decode_next(&utf8);
if (c < 0) {
- return UTF8_END ? the_index : UTF8_ERROR;
+ return (c == UTF8_END) ? the_index : UTF8_ERROR;
}
if (c < 0x10000) {
w[the_index] = (unsigned short)c;