mirror of
https://github.com/json-c/json-c.git
synced 2026-09-07 08:36:50 +08:00
Merge pull request #957 from dngr2/fix/strict-number-grammar
Check the whole RFC 8259 number grammar in strict mode
This commit is contained in:
+57
-5
@@ -1045,15 +1045,67 @@ struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *
|
||||
}
|
||||
if (tok->flags & JSON_TOKENER_STRICT)
|
||||
{
|
||||
/* RFC 8259 forbids leading zeros in the integer part:
|
||||
* a '0' may only be followed by '.', 'e'/'E' or the end
|
||||
* of the number, so "01", "00" and "-0123" are invalid
|
||||
* while "0", "-0" and "0.5" remain valid.
|
||||
/* Check the accumulated text against the RFC 8259 grammar:
|
||||
*
|
||||
* number = [ minus ] int [ frac ] [ exp ]
|
||||
* int = zero / ( digit1-9 *DIGIT )
|
||||
* frac = decimal-point 1*DIGIT
|
||||
* exp = e [ minus / plus ] 1*DIGIT
|
||||
*
|
||||
* so the integer part is mandatory and may not carry a
|
||||
* leading zero, and both the fraction and the exponent
|
||||
* need at least one digit of their own. That rejects
|
||||
* "01", ".5", "-.123", "1.", "2.e3" and "1e", while
|
||||
* "0", "-0", "0.5" and "2e3" stay valid.
|
||||
*/
|
||||
const char *num = tok->pb->buf;
|
||||
if (*num == '-')
|
||||
num++;
|
||||
if (num[0] == '0' && num[1] >= '0' && num[1] <= '9')
|
||||
if (*num == '0')
|
||||
{
|
||||
num++;
|
||||
if (*num >= '0' && *num <= '9')
|
||||
{
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (*num >= '1' && *num <= '9')
|
||||
{
|
||||
while (*num >= '0' && *num <= '9')
|
||||
num++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no integer part at all, e.g. ".5" or "-.123" */
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
}
|
||||
if (*num == '.')
|
||||
{
|
||||
num++;
|
||||
if (!(*num >= '0' && *num <= '9'))
|
||||
{
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
}
|
||||
while (*num >= '0' && *num <= '9')
|
||||
num++;
|
||||
}
|
||||
if (*num == 'e' || *num == 'E')
|
||||
{
|
||||
num++;
|
||||
if (*num == '+' || *num == '-')
|
||||
num++;
|
||||
if (!(*num >= '0' && *num <= '9'))
|
||||
{
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
}
|
||||
while (*num >= '0' && *num <= '9')
|
||||
num++;
|
||||
}
|
||||
if (*num != '\0')
|
||||
{
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
|
||||
@@ -375,6 +375,24 @@ struct incremental_step
|
||||
/* ... but a lone zero, "-0" and a zero before the fraction stay valid. */
|
||||
{"[-0]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
|
||||
{"[0.5]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
|
||||
/* RFC 8259 wants a digit either side of the decimal point and after the
|
||||
* exponent marker, so a bare "1." or "2.e3" is not a number ... */
|
||||
{"[1.]", -1, 3, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
|
||||
{"[-2.]", -1, 4, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
|
||||
{"[2.e3]", -1, 5, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
|
||||
{"[2.e+3]", -1, 6, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
|
||||
{"[0.e1]", -1, 5, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
|
||||
{"[1e]", -1, 3, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
|
||||
{"[1e+]", -1, 4, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
|
||||
/* ... and the integer part is mandatory, so "-.123" is not a number either
|
||||
* (a bare ".5" never reaches the number state at all). */
|
||||
{"[-.123]", -1, 6, json_tokener_error_parse_number, 1, JSON_TOKENER_STRICT},
|
||||
/* The well-formed spellings of the same values stay valid. */
|
||||
{"[1.0]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
|
||||
{"[2e3]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
|
||||
{"[2E-3]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
|
||||
{"[0.123]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
|
||||
{"[-0.123]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
|
||||
|
||||
{"0e+0", 5, 4, json_tokener_success, 1, 0},
|
||||
{"[0e+0]", -1, -1, json_tokener_success, 1, 0},
|
||||
|
||||
@@ -163,6 +163,19 @@ json_tokener_parse_ex(tok, [-0123] , 7) ... OK: got correct error: number
|
||||
json_tokener_parse_ex(tok, [01.5] , 6) ... OK: got correct error: number expected
|
||||
json_tokener_parse_ex(tok, [-0] , 4) ... OK: got object of type [array]: [ 0 ]
|
||||
json_tokener_parse_ex(tok, [0.5] , 5) ... OK: got object of type [array]: [ 0.5 ]
|
||||
json_tokener_parse_ex(tok, [1.] , 4) ... OK: got correct error: number expected
|
||||
json_tokener_parse_ex(tok, [-2.] , 5) ... OK: got correct error: number expected
|
||||
json_tokener_parse_ex(tok, [2.e3] , 6) ... OK: got correct error: number expected
|
||||
json_tokener_parse_ex(tok, [2.e+3] , 7) ... OK: got correct error: number expected
|
||||
json_tokener_parse_ex(tok, [0.e1] , 6) ... OK: got correct error: number expected
|
||||
json_tokener_parse_ex(tok, [1e] , 4) ... OK: got correct error: number expected
|
||||
json_tokener_parse_ex(tok, [1e+] , 5) ... OK: got correct error: number expected
|
||||
json_tokener_parse_ex(tok, [-.123] , 7) ... OK: got correct error: number expected
|
||||
json_tokener_parse_ex(tok, [1.0] , 5) ... OK: got object of type [array]: [ 1.0 ]
|
||||
json_tokener_parse_ex(tok, [2e3] , 5) ... OK: got object of type [array]: [ 2e3 ]
|
||||
json_tokener_parse_ex(tok, [2E-3] , 6) ... OK: got object of type [array]: [ 2E-3 ]
|
||||
json_tokener_parse_ex(tok, [0.123] , 7) ... OK: got object of type [array]: [ 0.123 ]
|
||||
json_tokener_parse_ex(tok, [-0.123] , 8) ... OK: got object of type [array]: [ -0.123 ]
|
||||
json_tokener_parse_ex(tok, 0e+0 , 5) ... OK: got object of type [double]: 0e+0
|
||||
json_tokener_parse_ex(tok, [0e+0] , 6) ... OK: got object of type [array]: [ 0e+0 ]
|
||||
json_tokener_parse_ex(tok, 0e , 2) ... OK: got correct error: continue
|
||||
@@ -375,5 +388,5 @@ json_tokener_parse_ex(tok, {"":1} , 7) ... OK: got correct error: invalid
|
||||
json_tokener_parse_ex(tok, {"":1} , 7) ... OK: got correct error: invalid string sequence
|
||||
json_tokener_parse_ex(tok, {"":1} , 7) ... OK: got correct error: invalid string sequence
|
||||
json_tokener_parse_ex(tok, {"":1} , 7) ... OK: got correct error: invalid string sequence
|
||||
End Incremental Tests OK=279 ERROR=0
|
||||
End Incremental Tests OK=292 ERROR=0
|
||||
==================================
|
||||
|
||||
Reference in New Issue
Block a user