Add JSON_ALLOW_NUL decoding flag for enabling NUL byte support
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -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:
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
12
src/load.c
12
src/load.c
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
["null char \u0000 in string"]
|
||||
@@ -1 +0,0 @@
|
||||
["null char \u0000 in string"]
|
||||
Reference in New Issue
Block a user