JSON numbers should take the following form: * -?(0|[1-9]|[1-9][0-9]+)(.[0-9]+)?([eE][-+]?[0-9]+)? * * json_next_number_token() uses strtod() which allows other forms: * - numbers starting with '+' * - NaN, -NaN, infinity, -infinity * - hexadecimal numbers * - numbers with leading zeros * * json_is_invalid_number() detects "numbers" which may pass strtod()'s * error checking, but sh
| 958 | * to generate an error. |
| 959 | */ |
| 960 | static int json_is_invalid_number(json_parse_t *json) |
| 961 | { |
| 962 | const char *p = json->ptr; |
| 963 | |
| 964 | /* Reject numbers starting with + */ |
| 965 | if (*p == '+') |
| 966 | return 1; |
| 967 | |
| 968 | /* Skip minus sign if it exists */ |
| 969 | if (*p == '-') |
| 970 | p++; |
| 971 | |
| 972 | /* Reject numbers starting with 0x, or leading zeros */ |
| 973 | if (*p == '0') { |
| 974 | int ch2 = *(p + 1); |
| 975 | |
| 976 | if ((ch2 | 0x20) == 'x' || /* Hex */ |
| 977 | ('0' <= ch2 && ch2 <= '9')) /* Leading zero */ |
| 978 | return 1; |
| 979 | |
| 980 | return 0; |
| 981 | } else if (*p <= '9') { |
| 982 | return 0; /* Ordinary number */ |
| 983 | } |
| 984 | |
| 985 | /* Reject inf/nan */ |
| 986 | if (!strncasecmp(p, "inf", 3)) |
| 987 | return 1; |
| 988 | if (!strncasecmp(p, "nan", 3)) |
| 989 | return 1; |
| 990 | |
| 991 | /* Pass all other numbers which may still be invalid, but |
| 992 | * strtod() will catch them. */ |
| 993 | return 0; |
| 994 | } |
| 995 | |
| 996 | static void json_next_number_token(json_parse_t *json, json_token_t *token) |
| 997 | { |