MDEV-32587 Allow json exponential notation starting with zero

Modify the NS_ZERO state in the JSON number parser to allow
exponential notation with a zero coefficient (e.g. 0E-4).

The NS_ZERO state transition on 'E' was updated to move to the
NS_EX state rather than returning a syntax error. Similar change
was made for the NS_ZE1 (negative zero) starter state.

This allows accepted number grammar to include cases like:

- 0E4
- -0E-10

which were previously disallowed. Numeric parsing remains
the same for all other states.

Test cases are added to func_json.test to validate parsing for
various exponential numbers starting with zero coefficients.

All new code of the whole pull request, including one or several files
that are either new files or modified ones, are contributed under the
BSD-new license. I am contributing on behalf of my employer Amazon Web
Services.
This commit is contained in:
Robin Newhouse 2023-12-07 00:16:28 +00:00 committed by Rucha Deodhar
parent 8e337e016f
commit 615f4a8c9e
3 changed files with 52 additions and 3 deletions

View file

@ -1300,5 +1300,38 @@ f
foo
SET @@COLLATION_CONNECTION= @old_collation_connection;
#
# MDEV-32587 JSON_VALID fail to validate integer zero in scientific notation
#
select JSON_VALID(' {"number": 1E-4}');
JSON_VALID(' {"number": 1E-4}')
1
select JSON_VALID(' {"number": 0E-4}');
JSON_VALID(' {"number": 0E-4}')
1
select JSON_VALID(' {"number": 0.0}');
JSON_VALID(' {"number": 0.0}')
1
select JSON_VALID(' {"number": 0.1E-4}');
JSON_VALID(' {"number": 0.1E-4}')
1
select JSON_VALID(' {"number": 0e-4}');
JSON_VALID(' {"number": 0e-4}')
1
select JSON_VALID(' {"number": -0E-4}');
JSON_VALID(' {"number": -0E-4}')
1
select JSON_VALUE(' {"number": 0E-4}', '$.number');
JSON_VALUE(' {"number": 0E-4}', '$.number')
0E-4
select JSON_VALID(' {"number": 00E-4}');
JSON_VALID(' {"number": 00E-4}')
0
select JSON_VALID(' {"number": 01E-4}');
JSON_VALID(' {"number": 01E-4}')
0
select JSON_VALID(' {"number": 0E-4.0}');
JSON_VALID(' {"number": 0E-4.0}')
0
#
# End of 10.4 tests
#

View file

@ -840,6 +840,22 @@ SELECT JSON_VALUE('["foo"]', '$**[0]') AS f;
SET @@COLLATION_CONNECTION= @old_collation_connection;
--echo #
--echo # MDEV-32587 JSON_VALID fail to validate integer zero in scientific notation
--echo #
# Passing
select JSON_VALID(' {"number": 1E-4}');
select JSON_VALID(' {"number": 0E-4}');
select JSON_VALID(' {"number": 0.0}');
select JSON_VALID(' {"number": 0.1E-4}');
select JSON_VALID(' {"number": 0e-4}');
select JSON_VALID(' {"number": -0E-4}');
select JSON_VALUE(' {"number": 0E-4}', '$.number');
# Failing
select JSON_VALID(' {"number": 00E-4}');
select JSON_VALID(' {"number": 01E-4}');
select JSON_VALID(' {"number": 0E-4.0}');
--echo #
--echo # End of 10.4 tests
--echo #

View file

@ -467,12 +467,12 @@ enum json_num_states {
static int json_num_states[NS_NUM_STATES][N_NUM_CLASSES]=
{
/* - + 0 1..9 POINT E END_OK ERROR */
/* - + 0 1..9 POINT E END_OK ERROR */
/*OK*/ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_BAD_CHR },
/*GO*/ { NS_GO1, JE_SYN, NS_Z, NS_INT, JE_SYN, JE_SYN, JE_SYN, JE_BAD_CHR },
/*GO1*/ { JE_SYN, JE_SYN, NS_Z1, NS_INT, JE_SYN, JE_SYN, JE_SYN, JE_BAD_CHR },
/*ZERO*/ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, NS_FRAC, JE_SYN, NS_OK, JE_BAD_CHR },
/*ZE1*/ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, NS_FRAC, JE_SYN, NS_OK, JE_BAD_CHR },
/*ZERO*/ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, NS_FRAC, NS_EX, NS_OK, JE_BAD_CHR },
/*ZE1*/ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, NS_FRAC, NS_EX, NS_OK, JE_BAD_CHR },
/*INT*/ { JE_SYN, JE_SYN, NS_INT, NS_INT, NS_FRAC, NS_EX, NS_OK, JE_BAD_CHR },
/*FRAC*/ { JE_SYN, JE_SYN, NS_FRAC, NS_FRAC,JE_SYN, NS_EX, NS_OK, JE_BAD_CHR },
/*EX*/ { NS_EX, NS_EX, NS_EX1, NS_EX1, JE_SYN, JE_SYN, JE_SYN, JE_BAD_CHR },