json-builder: do better json number check

If we are going to produce valid JSON we need to do a better JSON number
check because our own float and int parser can accept more variants
and will let through numbers that are not valid JSON.

See #5161
This commit is contained in:
Wim Taymans 2026-03-09 13:33:20 +01:00
parent 48c22e2aa7
commit 3a2d16a3bc
3 changed files with 77 additions and 16 deletions

View file

@ -169,11 +169,13 @@ void spa_json_builder_add_simple(struct spa_json_builder *b, const char *key, in
else if (spa_json_is_null(val, val_len) ||
spa_json_is_bool(val, val_len))
type = 'l';
else if (spa_json_is_float(val, val_len) ||
spa_json_is_int(val, val_len))
type = 'd';
else if (spa_json_is_string(val, val_len))
type = 's';
else if (spa_json_is_json_number(val, val_len))
type = 'd';
else if (simple && (spa_json_is_float(val, val_len) ||
spa_json_is_int(val, val_len)))
type = 'd';
else
type = 'S';
}

View file

@ -484,6 +484,44 @@ SPA_API_JSON bool spa_json_is_int(const char *val, int len)
return spa_json_parse_int(val, len, &dummy);
}
SPA_API_JSON bool spa_json_is_json_number(const char *val, int len)
{
int pos = 0, first;
/* integer */
if (len == 0)
return 0;
if (pos < len && val[pos] == '-')
pos++;
first = pos;
while(pos < len && val[pos] >= '0' && val[pos] <= '9')
pos++;
if (pos == first || (first + 1 < pos && val[first] == '0'))
return 0;
/* fraction */
if (pos == len)
return 1;
if (val[pos++] != '.')
return 0;
first = pos;
while(pos < len && val[pos] >= '0' && val[pos] <= '9')
pos++;
if (pos == first)
return 0;
/* exponent */
if (pos == len)
return 1;
if (val[pos] != 'e' && val[pos] != 'E')
return 0;
pos++;
if (val[pos] == '-' || val[pos] == '+')
pos++;
while(pos < len && val[pos] >= '0' && val[pos] <= '9')
pos++;
if (pos != len)
return 0;
return 1;
}
/* bool */
SPA_API_JSON bool spa_json_is_true(const char *val, int len)
{