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)
|
if (tok->flags & JSON_TOKENER_STRICT)
|
||||||
{
|
{
|
||||||
/* RFC 8259 forbids leading zeros in the integer part:
|
/* Check the accumulated text against the RFC 8259 grammar:
|
||||||
* a '0' may only be followed by '.', 'e'/'E' or the end
|
*
|
||||||
* of the number, so "01", "00" and "-0123" are invalid
|
* number = [ minus ] int [ frac ] [ exp ]
|
||||||
* while "0", "-0" and "0.5" remain valid.
|
* 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;
|
const char *num = tok->pb->buf;
|
||||||
if (*num == '-')
|
if (*num == '-')
|
||||||
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;
|
tok->err = json_tokener_error_parse_number;
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -375,6 +375,24 @@ struct incremental_step
|
|||||||
/* ... but a lone zero, "-0" and a zero before the fraction stay valid. */
|
/* ... but a lone zero, "-0" and a zero before the fraction stay valid. */
|
||||||
{"[-0]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
|
{"[-0]", -1, -1, json_tokener_success, 1, JSON_TOKENER_STRICT},
|
||||||
{"[0.5]", -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", 5, 4, json_tokener_success, 1, 0},
|
||||||
{"[0e+0]", -1, -1, 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, [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] , 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, [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 , 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+0] , 6) ... OK: got object of type [array]: [ 0e+0 ]
|
||||||
json_tokener_parse_ex(tok, 0e , 2) ... OK: got correct error: continue
|
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
|
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