mirror of
https://github.com/json-c/json-c.git
synced 2026-03-13 18:19:06 +08:00
Merge pull request #168 from bugness-chl/master
Tightening the number parsing algorithm
This commit is contained in:
@@ -668,10 +668,45 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
/* Advance until we change state */
|
/* Advance until we change state */
|
||||||
const char *case_start = str;
|
const char *case_start = str;
|
||||||
int case_len=0;
|
int case_len=0;
|
||||||
|
int is_exponent=0;
|
||||||
|
int negativesign_next_possible_location=1;
|
||||||
while(c && strchr(json_number_chars, c)) {
|
while(c && strchr(json_number_chars, c)) {
|
||||||
++case_len;
|
++case_len;
|
||||||
if(c == '.' || c == 'e' || c == 'E')
|
|
||||||
|
/* non-digit characters checks */
|
||||||
|
/* note: since the main loop condition to get here was
|
||||||
|
an input starting with 0-9 or '-', we are
|
||||||
|
protected from input starting with '.' or
|
||||||
|
e/E. */
|
||||||
|
if (c == '.') {
|
||||||
|
if (tok->is_double != 0) {
|
||||||
|
/* '.' can only be found once, and out of the exponent part.
|
||||||
|
Thus, if the input is already flagged as double, it
|
||||||
|
is invalid. */
|
||||||
|
tok->err = json_tokener_error_parse_number;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
tok->is_double = 1;
|
tok->is_double = 1;
|
||||||
|
}
|
||||||
|
if (c == 'e' || c == 'E') {
|
||||||
|
if (is_exponent != 0) {
|
||||||
|
/* only one exponent possible */
|
||||||
|
tok->err = json_tokener_error_parse_number;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
is_exponent = 1;
|
||||||
|
tok->is_double = 1;
|
||||||
|
/* the exponent part can begin with a negative sign */
|
||||||
|
negativesign_next_possible_location = case_len + 1;
|
||||||
|
}
|
||||||
|
if (c == '-' && case_len != negativesign_next_possible_location) {
|
||||||
|
/* If the negative sign is not where expected (ie
|
||||||
|
start of input or start of exponent part), the
|
||||||
|
input is invalid. */
|
||||||
|
tok->err = json_tokener_error_parse_number;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
||||||
printbuf_memappend_fast(tok->pb, case_start, case_len);
|
printbuf_memappend_fast(tok->pb, case_start, case_len);
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -91,6 +91,23 @@ static void test_basic_parse()
|
|||||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
json_object_put(new_obj);
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("12.3.4"); /* non-sensical, returns null */
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
/* was returning (int)2015 before patch, should return null */
|
||||||
|
new_obj = json_tokener_parse("2015-01-15");
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("{\"FoO\" : -12.3E512}");
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("{\"FoO\" : -12.3E51.2}"); /* non-sensical, returns null */
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
new_obj = json_tokener_parse("[\"\\n\"]");
|
new_obj = json_tokener_parse("[\"\\n\"]");
|
||||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
json_object_put(new_obj);
|
json_object_put(new_obj);
|
||||||
@@ -195,6 +212,9 @@ struct incremental_step {
|
|||||||
{ "1", 1, 1, json_tokener_continue, 0 },
|
{ "1", 1, 1, json_tokener_continue, 0 },
|
||||||
{ "2", 2, 1, json_tokener_success, 0 },
|
{ "2", 2, 1, json_tokener_success, 0 },
|
||||||
|
|
||||||
|
/* Some bad formatting. Check we get the correct error status */
|
||||||
|
{ "2015-01-15", 10, 4, json_tokener_error_parse_number, 1 },
|
||||||
|
|
||||||
/* Strings have a well defined end point, so we can stop at the quote */
|
/* Strings have a well defined end point, so we can stop at the quote */
|
||||||
{ "\"blue\"", -1, -1, json_tokener_success, 0 },
|
{ "\"blue\"", -1, -1, json_tokener_success, 0 },
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ new_obj.to_string()=-Infinity
|
|||||||
new_obj.to_string()=true
|
new_obj.to_string()=true
|
||||||
new_obj.to_string()=12
|
new_obj.to_string()=12
|
||||||
new_obj.to_string()=12.3
|
new_obj.to_string()=12.3
|
||||||
|
new_obj.to_string()=null
|
||||||
|
new_obj.to_string()=null
|
||||||
|
new_obj.to_string()={ "FoO": -12.3E512 }
|
||||||
|
new_obj.to_string()=null
|
||||||
new_obj.to_string()=[ "\n" ]
|
new_obj.to_string()=[ "\n" ]
|
||||||
new_obj.to_string()=[ "\nabc\n" ]
|
new_obj.to_string()=[ "\nabc\n" ]
|
||||||
new_obj.to_string()=[ null ]
|
new_obj.to_string()=[ null ]
|
||||||
@@ -48,6 +52,7 @@ json_tokener_parse_ex(tok, {"x": 123 }"X", 14) ... OK: got object of type [obje
|
|||||||
json_tokener_parse_ex(tok, "Y" , 3) ... OK: got object of type [string]: "Y"
|
json_tokener_parse_ex(tok, "Y" , 3) ... OK: got object of type [string]: "Y"
|
||||||
json_tokener_parse_ex(tok, 1 , 1) ... OK: got correct error: continue
|
json_tokener_parse_ex(tok, 1 , 1) ... OK: got correct error: continue
|
||||||
json_tokener_parse_ex(tok, 2 , 2) ... OK: got object of type [int]: 12
|
json_tokener_parse_ex(tok, 2 , 2) ... OK: got object of type [int]: 12
|
||||||
|
json_tokener_parse_ex(tok, 2015-01-15 , 10) ... OK: got correct error: number expected
|
||||||
json_tokener_parse_ex(tok, "blue" , 6) ... OK: got object of type [string]: "blue"
|
json_tokener_parse_ex(tok, "blue" , 6) ... OK: got object of type [string]: "blue"
|
||||||
json_tokener_parse_ex(tok, "\"" , 4) ... OK: got object of type [string]: "\""
|
json_tokener_parse_ex(tok, "\"" , 4) ... OK: got object of type [string]: "\""
|
||||||
json_tokener_parse_ex(tok, "\\" , 4) ... OK: got object of type [string]: "\\"
|
json_tokener_parse_ex(tok, "\\" , 4) ... OK: got object of type [string]: "\\"
|
||||||
@@ -61,5 +66,5 @@ json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got object of type [array]
|
|||||||
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
|
||||||
json_tokener_parse_ex(tok, [1,2,3,] , 8) ... OK: got correct error: unexpected character
|
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
|
json_tokener_parse_ex(tok, {"a":1,} , 8) ... OK: got correct error: unexpected character
|
||||||
End Incremental Tests OK=29 ERROR=0
|
End Incremental Tests OK=30 ERROR=0
|
||||||
==================================
|
==================================
|
||||||
|
|||||||
Reference in New Issue
Block a user