Skip to content

Commit

Permalink
MDEV-29264: JSON function overflow error based on LONGTEXT field
Browse files Browse the repository at this point in the history
Analysis: The JSON functions(JSON_ARRAY[OBJECT|ARRAY_APPEND|ARRAY_INSERT|INSERT|SET|REPLACE]) result is truncated when the function is called based on LONGTEXT field. The overflow occurs when computing the result length due to the LONGTEXT max length is same as uint32 max length. It lead to wrong result length.
Fix: Add static_cast<ulonglong> to avoid uint32 overflow and fix the arguments used.
  • Loading branch information
Ziy1-Tan authored and mariadb-RuchaDeodhar committed Aug 13, 2022
1 parent 5d3bbc6 commit 8201751
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
17 changes: 16 additions & 1 deletion mysql-test/main/func_json.result
Expand Up @@ -822,7 +822,7 @@ CREATE TABLE t2 SELECT JSON_ARRAY_INSERT(fld, '$.[0]', '0') FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`JSON_ARRAY_INSERT(fld, '$.[0]', '0')` varchar(25) DEFAULT NULL
`JSON_ARRAY_INSERT(fld, '$.[0]', '0')` varchar(21) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1, t2;
SET sql_mode=default;
Expand Down Expand Up @@ -1437,5 +1437,20 @@ f
DROP VIEW v;
DROP TABLE t;
#
# MDEV-29264 JSON functions overflow error based ON LONGTEXT field
#
CREATE TABLE t(l1 LONGTEXT, l2 LONGTEXT, l3 LONGTEXT, l4 LONGTEXT);
INSERT INTO t VALUES('k1', 'v1', 'k2', 'v2');
SELECT JSON_ARRAY(l1, l2, l3, l4), JSON_OBJECT(l1, l2, l3, l4) from t;
JSON_ARRAY(l1, l2, l3, l4) JSON_OBJECT(l1, l2, l3, l4)
["k1", "v1", "k2", "v2"] {"k1": "v1", "k2": "v2"}
SELECT JSON_ARRAY_APPEND(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3'), JSON_ARRAY_INSERT(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3') from t;
JSON_ARRAY_APPEND(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3') JSON_ARRAY_INSERT(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3')
[["k1", "k3"], "v1", "k2", "v2"] ["k3", "k1", "v1", "k2", "v2"]
SELECT JSON_INSERT(JSON_OBJECT(l1, l2, l3, l4), '$.k3', 'v3'),JSON_SET(JSON_OBJECT(l1, l2, l3, l4), '$.k2', 'new v2'),JSON_REPLACE(JSON_OBJECT(l1, l2, l3, l4), '$.k2', 'new v2') from t;
JSON_INSERT(JSON_OBJECT(l1, l2, l3, l4), '$.k3', 'v3') JSON_SET(JSON_OBJECT(l1, l2, l3, l4), '$.k2', 'new v2') JSON_REPLACE(JSON_OBJECT(l1, l2, l3, l4), '$.k2', 'new v2')
{"k1": "v1", "k2": "v2", "k3": "v3"} {"k1": "v1", "k2": "new v2"} {"k1": "v1", "k2": "new v2"}
DROP TABLE t;
#
# End of 10.5 tests
#
11 changes: 11 additions & 0 deletions mysql-test/main/func_json.test
Expand Up @@ -927,6 +927,17 @@ SELECT JSON_ARRAYAGG(a) AS f FROM v;
DROP VIEW v;
DROP TABLE t;


--echo #
--echo # MDEV-29264 JSON functions overflow error based ON LONGTEXT field
--echo #
CREATE TABLE t(l1 LONGTEXT, l2 LONGTEXT, l3 LONGTEXT, l4 LONGTEXT);
INSERT INTO t VALUES('k1', 'v1', 'k2', 'v2');
SELECT JSON_ARRAY(l1, l2, l3, l4), JSON_OBJECT(l1, l2, l3, l4) from t;
SELECT JSON_ARRAY_APPEND(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3'), JSON_ARRAY_INSERT(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3') from t;
SELECT JSON_INSERT(JSON_OBJECT(l1, l2, l3, l4), '$.k3', 'v3'),JSON_SET(JSON_OBJECT(l1, l2, l3, l4), '$.k2', 'new v2'),JSON_REPLACE(JSON_OBJECT(l1, l2, l3, l4), '$.k2', 'new v2') from t;
DROP TABLE t;

--echo #
--echo # End of 10.5 tests
--echo #
Expand Down
8 changes: 5 additions & 3 deletions sql/item_jsonfunc.cc
Expand Up @@ -1738,7 +1738,7 @@ bool Item_func_json_array::fix_length_and_dec()
return TRUE;

for (n_arg=0 ; n_arg < arg_count ; n_arg++)
char_length+= args[n_arg]->max_char_length() + 4;
char_length+= static_cast<ulonglong>(args[n_arg]->max_char_length()) + 4;

fix_char_length_ulonglong(char_length);
tmp_val.set_charset(collation.collation);
Expand Down Expand Up @@ -1797,7 +1797,8 @@ bool Item_func_json_array_append::fix_length_and_dec()
for (n_arg= 1; n_arg < arg_count; n_arg+= 2)
{
paths[n_arg/2].set_constant_flag(args[n_arg]->const_item());
char_length+= args[n_arg/2+1]->max_char_length() + 4;
char_length+=
static_cast<ulonglong>(args[n_arg+1]->max_char_length()) + 4;
}

fix_char_length_ulonglong(char_length);
Expand Down Expand Up @@ -2959,7 +2960,8 @@ bool Item_func_json_insert::fix_length_and_dec()
for (n_arg= 1; n_arg < arg_count; n_arg+= 2)
{
paths[n_arg/2].set_constant_flag(args[n_arg]->const_item());
char_length+= args[n_arg/2+1]->max_char_length() + 4;
char_length+=
static_cast<ulonglong>(args[n_arg+1]->max_char_length()) + 4;
}

fix_char_length_ulonglong(char_length);
Expand Down

0 comments on commit 8201751

Please sign in to comment.