mirror of
https://github.com/json-c/json-c.git
synced 2026-04-05 13:29:06 +08:00
Issue #15: add a way to set a JSON_TOKENER_STRICT flag to forbid commas at the end of arrays and objects.
This commit is contained in:
@@ -624,8 +624,15 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case json_tokener_state_array_after_sep:
|
||||||
case json_tokener_state_array:
|
case json_tokener_state_array:
|
||||||
if(c == ']') {
|
if(c == ']') {
|
||||||
|
if (state == json_tokener_state_array_after_sep &&
|
||||||
|
(tok->flags & JSON_TOKENER_STRICT))
|
||||||
|
{
|
||||||
|
tok->err = json_tokener_error_parse_unexpected;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else {
|
} else {
|
||||||
@@ -651,7 +658,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else if(c == ',') {
|
} else if(c == ',') {
|
||||||
saved_state = json_tokener_state_array;
|
saved_state = json_tokener_state_array_after_sep;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else {
|
} else {
|
||||||
tok->err = json_tokener_error_parse_array;
|
tok->err = json_tokener_error_parse_array;
|
||||||
@@ -660,7 +667,14 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case json_tokener_state_object_field_start:
|
case json_tokener_state_object_field_start:
|
||||||
|
case json_tokener_state_object_field_start_after_sep:
|
||||||
if(c == '}') {
|
if(c == '}') {
|
||||||
|
if (state == json_tokener_state_object_field_start_after_sep &&
|
||||||
|
(tok->flags & JSON_TOKENER_STRICT))
|
||||||
|
{
|
||||||
|
tok->err = json_tokener_error_parse_unexpected;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else if (c == '"' || c == '\'') {
|
} else if (c == '"' || c == '\'') {
|
||||||
@@ -731,7 +745,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else if(c == ',') {
|
} else if(c == ',') {
|
||||||
saved_state = json_tokener_state_object_field_start;
|
saved_state = json_tokener_state_object_field_start_after_sep;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else {
|
} else {
|
||||||
tok->err = json_tokener_error_parse_object_value_sep;
|
tok->err = json_tokener_error_parse_object_value_sep;
|
||||||
@@ -771,3 +785,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
json_tokener_errors[tok->err], tok->char_offset);
|
json_tokener_errors[tok->err], tok->char_offset);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void json_tokener_set_flags(struct json_tokener *tok, int flags)
|
||||||
|
{
|
||||||
|
tok->flags = flags;
|
||||||
|
}
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ enum json_tokener_state {
|
|||||||
json_tokener_state_object_field_end,
|
json_tokener_state_object_field_end,
|
||||||
json_tokener_state_object_value,
|
json_tokener_state_object_value,
|
||||||
json_tokener_state_object_value_add,
|
json_tokener_state_object_value_add,
|
||||||
json_tokener_state_object_sep
|
json_tokener_state_object_sep,
|
||||||
|
json_tokener_state_array_after_sep,
|
||||||
|
json_tokener_state_object_field_start_after_sep
|
||||||
};
|
};
|
||||||
|
|
||||||
struct json_tokener_srec
|
struct json_tokener_srec
|
||||||
@@ -80,8 +82,21 @@ struct json_tokener
|
|||||||
unsigned int ucs_char;
|
unsigned int ucs_char;
|
||||||
char quote_char;
|
char quote_char;
|
||||||
struct json_tokener_srec *stack;
|
struct json_tokener_srec *stack;
|
||||||
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Be strict when parsing JSON input. Use caution with
|
||||||
|
* this flag as what is considered valid may become more
|
||||||
|
* restrictive from one release to the next, causing your
|
||||||
|
* code to fail on previously working input.
|
||||||
|
*
|
||||||
|
* This flag is not set by default.
|
||||||
|
*
|
||||||
|
* @see json_tokener_set_flags()
|
||||||
|
*/
|
||||||
|
#define JSON_TOKENER_STRICT 0x01
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an error previously returned by json_tokener_get_error(),
|
* Given an error previously returned by json_tokener_get_error(),
|
||||||
* return a human readable description of the error.
|
* return a human readable description of the error.
|
||||||
@@ -116,6 +131,11 @@ extern void json_tokener_reset(struct json_tokener *tok);
|
|||||||
extern struct json_object* json_tokener_parse(const char *str);
|
extern struct json_object* json_tokener_parse(const char *str);
|
||||||
extern struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);
|
extern struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set flags that control how parsing will be done.
|
||||||
|
*/
|
||||||
|
extern void json_tokener_set_flags(struct json_tokener *tok, int flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a string and return a non-NULL json_object if a valid JSON value
|
* Parse a string and return a non-NULL json_object if a valid JSON value
|
||||||
* is found. The string does not need to be a JSON object or array;
|
* is found. The string does not need to be a JSON object or array;
|
||||||
|
|||||||
@@ -183,6 +183,9 @@ struct incremental_step {
|
|||||||
{ "[1,2,3,]", -1, -1, json_tokener_success, 0 },
|
{ "[1,2,3,]", -1, -1, json_tokener_success, 0 },
|
||||||
{ "[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0 },
|
{ "[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0 },
|
||||||
|
|
||||||
|
{ "[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 3 },
|
||||||
|
{ "{\"a\":1,}", -1, 7, json_tokener_error_parse_unexpected, 3 },
|
||||||
|
|
||||||
{ NULL, -1, -1, json_tokener_success, 0 },
|
{ NULL, -1, -1, json_tokener_success, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -215,6 +218,12 @@ static void test_incremental_parse()
|
|||||||
struct incremental_step *step = &incremental_steps[ii];
|
struct incremental_step *step = &incremental_steps[ii];
|
||||||
int length = step->length;
|
int length = step->length;
|
||||||
int expected_char_offset = step->char_offset;
|
int expected_char_offset = step->char_offset;
|
||||||
|
|
||||||
|
if (step->reset_tokener & 2)
|
||||||
|
json_tokener_set_flags(tok, JSON_TOKENER_STRICT);
|
||||||
|
else
|
||||||
|
json_tokener_set_flags(tok, 0);
|
||||||
|
|
||||||
if (length == -1)
|
if (length == -1)
|
||||||
length = strlen(step->string_to_parse);
|
length = strlen(step->string_to_parse);
|
||||||
if (expected_char_offset == -1)
|
if (expected_char_offset == -1)
|
||||||
@@ -264,7 +273,7 @@ static void test_incremental_parse()
|
|||||||
if (new_obj)
|
if (new_obj)
|
||||||
json_object_put(new_obj);
|
json_object_put(new_obj);
|
||||||
|
|
||||||
if (step->reset_tokener)
|
if (step->reset_tokener & 1)
|
||||||
json_tokener_reset(tok);
|
json_tokener_reset(tok);
|
||||||
|
|
||||||
if (this_step_ok)
|
if (this_step_ok)
|
||||||
|
|||||||
@@ -51,5 +51,7 @@ json_tokener_parse_ex(tok, "\t" , 4) ... OK: got object of type [string
|
|||||||
json_tokener_parse_ex(tok, [1,2,3] , 7) ... OK: got object of type [array]: [ 1, 2, 3 ]
|
json_tokener_parse_ex(tok, [1,2,3] , 7) ... OK: got object of type [array]: [ 1, 2, 3 ]
|
||||||
json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got object of type [array]: [ 1, 2, 3 ]
|
json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got object of type [array]: [ 1, 2, 3 ]
|
||||||
json_tokener_parse_ex(tok, [1,2,,3,] , 9) ... OK: got correct error: unexpected character
|
json_tokener_parse_ex(tok, [1,2,,3,] , 9) ... OK: got correct error: unexpected character
|
||||||
End Incremental Tests OK=27 ERROR=0
|
json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got correct error: unexpected character
|
||||||
|
json_tokener_parse_ex(tok, {"a":1,} , 8) ... OK: got correct error: unexpected character
|
||||||
|
End Incremental Tests OK=29 ERROR=0
|
||||||
==================================
|
==================================
|
||||||
|
|||||||
Reference in New Issue
Block a user