| @@ -135,6 +135,7 @@ static int json_escape_str(struct printbuf *pb, const char *str, int len, int fl | |||||
| else if(c == '\t') printbuf_memappend(pb, "\\t", 2); | else if(c == '\t') printbuf_memappend(pb, "\\t", 2); | ||||
| else if(c == '\f') printbuf_memappend(pb, "\\f", 2); | else if(c == '\f') printbuf_memappend(pb, "\\f", 2); | ||||
| else if(c == '"') printbuf_memappend(pb, "\\\"", 2); | else if(c == '"') printbuf_memappend(pb, "\\\"", 2); | ||||
| else if(c == '\\' && !strncmp(str + pos, "\\u0000", 6)) printbuf_memappend(pb, "\\", 1); | |||||
| else if(c == '\\') printbuf_memappend(pb, "\\\\", 2); | else if(c == '\\') printbuf_memappend(pb, "\\\\", 2); | ||||
| else if(c == '/') printbuf_memappend(pb, "\\/", 2); | else if(c == '/') printbuf_memappend(pb, "\\/", 2); | ||||
| @@ -604,7 +604,10 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok, | |||||
| got_hi_surrogate = 0; | got_hi_surrogate = 0; | ||||
| } | } | ||||
| if (tok->ucs_char < 0x80) { | |||||
| if (tok->ucs_char == 0x00) { | |||||
| unsigned char nul_unescaped_utf[6] = "\\u0000"; | |||||
| printbuf_memappend_fast(tok->pb, (char*)nul_unescaped_utf, 6); | |||||
| } else if (tok->ucs_char < 0x80) { | |||||
| unescaped_utf[0] = tok->ucs_char; | unescaped_utf[0] = tok->ucs_char; | ||||
| printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1); | printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1); | ||||
| } else if (tok->ucs_char < 0x800) { | } else if (tok->ucs_char < 0x800) { | ||||
| @@ -1,3 +1,3 @@ | |||||
| JSON write result is correct: " \u0000 " | JSON write result is correct: " \u0000 " | ||||
| PASS | PASS | ||||
| Re-parsed object string len=3, chars=[32, 0, 32] | |||||
| Re-parsed object string len=8, chars=[32, 92, 117, 48, 48, 48, 48, 32] | |||||
| @@ -121,6 +121,7 @@ static void test_basic_parse() | |||||
| single_basic_parse("{ \"foo\": [null, \"foo\"] }", 0); | single_basic_parse("{ \"foo\": [null, \"foo\"] }", 0); | ||||
| single_basic_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }", 0); | single_basic_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }", 0); | ||||
| single_basic_parse("{ \"abc\": \"blue\nred\\ngreen\" }", 0); | single_basic_parse("{ \"abc\": \"blue\nred\\ngreen\" }", 0); | ||||
| single_basic_parse("{ \"foo\\u0000bar\": \"foo\\u0000bar\" }", 0); | |||||
| // Clear serializer for these tests so we see the actual parsed value. | // Clear serializer for these tests so we see the actual parsed value. | ||||
| single_basic_parse("null", 1); | single_basic_parse("null", 1); | ||||
| @@ -61,6 +61,7 @@ new_obj.to_string({ "foo": [null, "foo"] })={ "foo": [ null, "foo" ] } | |||||
| new_obj.to_string({ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "arr": [ 1, 2, 3, null, 5 ] })={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "arr": [ 1, 2, 3, null, 5 ] } | new_obj.to_string({ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "arr": [ 1, 2, 3, null, 5 ] })={ "abc": 12, "foo": "bar", "bool0": false, "bool1": true, "arr": [ 1, 2, 3, null, 5 ] } | ||||
| new_obj.to_string({ "abc": "blue | new_obj.to_string({ "abc": "blue | ||||
| red\ngreen" })={ "abc": "blue\nred\ngreen" } | red\ngreen" })={ "abc": "blue\nred\ngreen" } | ||||
| new_obj.to_string({ "foo\u0000bar": "foo\u0000bar" })={ "foo\u0000bar": "foo\u0000bar" } | |||||
| new_obj.to_string(null)=null | new_obj.to_string(null)=null | ||||
| new_obj.to_string(false)=false | new_obj.to_string(false)=false | ||||
| new_obj.to_string([0e])=[ 0.0 ] | new_obj.to_string([0e])=[ 0.0 ] | ||||