Skip to content

Commit

Permalink
MDEV-31147 json_normalize does not work correctly with MSAN build
Browse files Browse the repository at this point in the history
json_normalize_number(): Avoid accessing str past str_len.
The function would seem to work incorrectly when some digits are
not followed by a decimal point (.) or an exponent (E or e).
  • Loading branch information
dr-m committed Apr 28, 2023
1 parent 5028b7c commit 7d96742
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 7 deletions.
13 changes: 13 additions & 0 deletions mysql-test/main/func_json.result
Original file line number Diff line number Diff line change
Expand Up @@ -1673,3 +1673,16 @@ DROP TABLE t;
#
# End of 10.6 tests
#
#
# MDEV-31147 json_normalize does not work correctly with MSAN build
#
CREATE TABLE t1 (val JSON);
ALTER TABLE t1 ADD COLUMN normalized_json JSON AS (JSON_NORMALIZE(val));
INSERT INTO t1 (val) VALUES ('15');
SELECT * FROM t1;
val normalized_json
15 1.5E1
DROP TABLE t1;
#
# End of 10.8 tests
#
13 changes: 13 additions & 0 deletions mysql-test/main/func_json.test
Original file line number Diff line number Diff line change
Expand Up @@ -1112,3 +1112,16 @@ DROP TABLE t;
--echo #
--echo # End of 10.6 tests
--echo #

--echo #
--echo # MDEV-31147 json_normalize does not work correctly with MSAN build
--echo #
CREATE TABLE t1 (val JSON);
ALTER TABLE t1 ADD COLUMN normalized_json JSON AS (JSON_NORMALIZE(val));
INSERT INTO t1 (val) VALUES ('15');
SELECT * FROM t1;
DROP TABLE t1;

--echo #
--echo # End of 10.8 tests
--echo #
17 changes: 10 additions & 7 deletions strings/json_normalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,16 @@ json_normalize_number(DYNAMIC_STRING *out, const char *str, size_t str_len)

magnitude = (long)(j - 1);

/* skip the . */
if (str[i] == '.')
++i;
if (i < str_len)
{
/* skip the . */
if (str[i] == '.')
++i;

/* grab rest of digits before the E */
for (; i < str_len && str[i] != 'e' && str[i] != 'E'; ++i)
buf[j++] = str[i];
/* grab rest of digits before the E */
for (; i < str_len && str[i] != 'e' && str[i] != 'E'; ++i)
buf[j++] = str[i];
}

/* trim trailing zeros */
for (k = j - 1; k && buf[k] == '0'; --k, --j)
Expand Down Expand Up @@ -187,7 +190,7 @@ json_normalize_number(DYNAMIC_STRING *out, const char *str, size_t str_len)

err|= dynstr_append_mem(out, STRING_WITH_LEN("E"));

if (str[i] == 'e' || str[i] == 'E')
if (i < str_len && (str[i] == 'e' || str[i] == 'E'))
{
char *endptr = NULL;
/* skip the [eE] */
Expand Down

0 comments on commit 7d96742

Please sign in to comment.