| @@ -16,6 +16,9 @@ Significant changes and bug fixes | |||||
| closing curly or square braces on same line for empty objects or arrays. | closing curly or square braces on same line for empty objects or arrays. | ||||
| * Disable locale handling when targeting a uClibc system due to problems | * Disable locale handling when targeting a uClibc system due to problems | ||||
| with its duplocale() function. | with its duplocale() function. | ||||
| * When parsing with JSON_TOKENER_STRICT set, integer overflow/underflow | |||||
| now result in a json_tokener_error_parse_number. Without that flag | |||||
| values are capped at INT64_MIN/UINT64_MAX. | |||||
| 0.16 (up to commit 66dcdf5, 2022-04-13) | 0.16 (up to commit 66dcdf5, 2022-04-13) | ||||
| @@ -17,6 +17,7 @@ | |||||
| #include "math_compat.h" | #include "math_compat.h" | ||||
| #include <assert.h> | #include <assert.h> | ||||
| #include <errno.h> | |||||
| #include <limits.h> | #include <limits.h> | ||||
| #include <math.h> | #include <math.h> | ||||
| #include <stddef.h> | #include <stddef.h> | ||||
| @@ -991,6 +992,11 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * | |||||
| if (!tok->is_double && tok->pb->buf[0] == '-' && | if (!tok->is_double && tok->pb->buf[0] == '-' && | ||||
| json_parse_int64(tok->pb->buf, &num64) == 0) | json_parse_int64(tok->pb->buf, &num64) == 0) | ||||
| { | { | ||||
| if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT)) | |||||
| { | |||||
| tok->err = json_tokener_error_parse_number; | |||||
| goto out; | |||||
| } | |||||
| current = json_object_new_int64(num64); | current = json_object_new_int64(num64); | ||||
| if (current == NULL) | if (current == NULL) | ||||
| goto out; | goto out; | ||||
| @@ -998,6 +1004,11 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char * | |||||
| else if (!tok->is_double && tok->pb->buf[0] != '-' && | else if (!tok->is_double && tok->pb->buf[0] != '-' && | ||||
| json_parse_uint64(tok->pb->buf, &numuint64) == 0) | json_parse_uint64(tok->pb->buf, &numuint64) == 0) | ||||
| { | { | ||||
| if (errno == ERANGE && (tok->flags & JSON_TOKENER_STRICT)) | |||||
| { | |||||
| tok->err = json_tokener_error_parse_number; | |||||
| goto out; | |||||
| } | |||||
| if (numuint64 && tok->pb->buf[0] == '0' && | if (numuint64 && tok->pb->buf[0] == '0' && | ||||
| (tok->flags & JSON_TOKENER_STRICT)) | (tok->flags & JSON_TOKENER_STRICT)) | ||||
| { | { | ||||
| @@ -438,6 +438,38 @@ struct incremental_step | |||||
| {"1234", 5, 0, json_tokener_success, 0, 0}, | {"1234", 5, 0, json_tokener_success, 0, 0}, | ||||
| {"1234", 5, 4, json_tokener_success, 1, 0}, | {"1234", 5, 4, json_tokener_success, 1, 0}, | ||||
| /* INT64_MAX */ | |||||
| {"[9223372036854775807]", 22, 21, json_tokener_success, 1, 0}, | |||||
| /* INT64_MAX+1 => parsed as uint64 */ | |||||
| {"[9223372036854775808]", 22, 21, json_tokener_success, 1, 0}, | |||||
| /* INT64_MIN */ | |||||
| {"[-9223372036854775808]", 23, 22, json_tokener_success, 1, 0}, | |||||
| /* INT64_MIN-1 => success, but value ends up capped */ | |||||
| {"[-9223372036854775809]", 23, 22, json_tokener_success, 1, 0}, | |||||
| /* INT64_MIN-1 => failure due to underflow detected */ | |||||
| {"[-9223372036854775809]", 23, 21, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT}, | |||||
| /* UINT64_MAX */ | |||||
| {"[18446744073709551615]", 23, 22, json_tokener_success, 1, 0}, | |||||
| /* UINT64_MAX+1 => success, but value ends up capped */ | |||||
| {"[18446744073709551616]", 23, 22, json_tokener_success, 1, 0}, | |||||
| /* UINT64_MAX+1 => failure due to overflow detected */ | |||||
| {"[18446744073709551616]", 23, 21, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT}, | |||||
| /* XXX this seems like a bug, should fail with _error_parse_number instead */ | |||||
| {"18446744073709551616", 21, 20, json_tokener_error_parse_eof, 1, JSON_TOKENER_STRICT}, | |||||
| /* Exceeding integer limits as double parse OK */ | |||||
| {"[9223372036854775808.0]", 24, 23, json_tokener_success, 1, 0}, | |||||
| {"[-9223372036854775809.0]", 25, 24, json_tokener_success, 1, JSON_TOKENER_STRICT}, | |||||
| {"[18446744073709551615.0]", 25, 24, json_tokener_success, 1, 0}, | |||||
| {"[18446744073709551616.0]", 25, 24, json_tokener_success, 1, JSON_TOKENER_STRICT}, | |||||
| /* offset=1 because "n" is the start of "null". hmm... */ | /* offset=1 because "n" is the start of "null". hmm... */ | ||||
| {"noodle", 7, 1, json_tokener_error_parse_null, 1, 0}, | {"noodle", 7, 1, json_tokener_error_parse_null, 1, 0}, | ||||
| /* offset=2 because "na" is the start of "nan". hmm... */ | /* offset=2 because "na" is the start of "nan". hmm... */ | ||||