Add JSON_ALLOW_NUL decoding flag for enabling NUL byte support

This commit is contained in:
Petri Lehtinen
2013-09-30 10:44:35 +03:00
parent 5744468c99
commit 1bfc33362e
7 changed files with 50 additions and 4 deletions

View File

@@ -16,7 +16,8 @@ Released XXXX-XX-XX
`json_string_setn()` and `json_string_setn_nocheck()`, and a
function for getting string's length `json_string_length()`.
- Support ``\u0000`` escapes in the decoder.
- Support ``\u0000`` escapes in the decoder. The support can be
enabled by using the ``JSON_ALLOW_NUL`` decoding flag.
* Bug fixes:

View File

@@ -244,6 +244,7 @@ json_t *json_deep_copy(const json_t *value);
#define JSON_DISABLE_EOF_CHECK 0x2
#define JSON_DECODE_ANY 0x4
#define JSON_DECODE_INT_AS_REAL 0x8
#define JSON_ALLOW_NUL 0x10
typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data);

View File

@@ -802,7 +802,17 @@ static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
switch(lex->token) {
case TOKEN_STRING: {
json = jsonp_stringn_nocheck_own(lex->value.string.val, lex->value.string.len);
const char *value = lex->value.string.val;
size_t len = lex->value.string.len;
if(!(flags & JSON_ALLOW_NUL)) {
if(memchr(value, '\0', len)) {
error_set(error, lex, "\\u0000 is not allowed without JSON_ALLOW_NUL");
return NULL;
}
}
json = jsonp_stringn_nocheck_own(value, len);
if(json) {
lex->value.string.val = NULL;
lex->value.string.len = 0;

View File

@@ -180,6 +180,20 @@ static void escape_slashes()
json_decref(json);
}
static void encode_nul_byte()
{
json_t *json;
char *result;
json = json_stringn("nul byte \0 in string", 20);
result = json_dumps(json, JSON_ENCODE_ANY);
if(!result || memcmp(result, "\"nul byte \\u0000 in string\"", 27))
fail("json_dumps failed to dump an embedded NUL byte");
free(result);
json_decref(json);
}
static void run_tests()
{
encode_null();
@@ -187,4 +201,5 @@ static void run_tests()
circular_references();
encode_other_than_array_or_object();
escape_slashes();
encode_nul_byte();
}

View File

@@ -115,6 +115,26 @@ static void decode_int_as_real()
#endif
}
static void allow_nul()
{
const char *text = "\"nul byte \\u0000 in string\"";
const char *expected = "nul byte \0 in string";
size_t len = 20;
json_t *json;
json = json_loads(text, JSON_ALLOW_NUL | JSON_DECODE_ANY, NULL);
if(!json || !json_is_string(json))
fail("unable to decode embedded NUL byte");
if(json_string_length(json) != len)
fail("decoder returned wrong string length");
if(memcmp(json_string_value(json), expected, len + 1))
fail("decoder returned wrong string content");
json_decref(json);
}
static void load_wrong_args()
{
json_t *json;
@@ -161,6 +181,7 @@ static void run_tests()
disable_eof_check();
decode_any();
decode_int_as_real();
allow_nul();
load_wrong_args();
position();
}

View File

@@ -1 +0,0 @@
["null char \u0000 in string"]

View File

@@ -1 +0,0 @@
["null char \u0000 in string"]