From 06bfac838ffb08e4775cfc2028d81c784a9b14e1 Mon Sep 17 00:00:00 2001 From: Abhishek Bansal Date: Tue, 3 Mar 2026 14:13:03 +0530 Subject: [PATCH] MDEV-37640: Crash at val_str in Item_func_json* functions This also fixes MDEV-33984. Item_func_json_normalize::val_str() and Item_func_json_keys::val_str failed to initialize the character set of the result buffer. In certain contexts, the buffer can be a zero-initialized String object with a NULL charset. This led to a null pointer dereference in String::append(), which relies on the charset information. Fixed by explicitly setting the buffer's charset to the item's collation before appending the normalized JSON string. --- mysql-test/main/func_json.result | 11 +++++++++++ mysql-test/main/func_json.test | 12 ++++++++++++ sql/item_jsonfunc.cc | 2 ++ 3 files changed, 25 insertions(+) diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index 46efc9003f14f..59fc725bd35a1 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -2770,4 +2770,15 @@ S1A1 SELECT JSON_VALUE('{"a":[1,2]}', '$.a[*]'); JSON_VALUE('{"a":[1,2]}', '$.a[*]') NULL +# +# MDEV-37640: Crash at String::append with json_normalize +# +SELECT ( WITH x AS ( WITH x AS ( SELECT 1.000000 ) SELECT ( REPEAT ( ( json_normalize ( ' -1' ) ) , 357 ) ) x ) SELECT x FROM x WHERE x IN ( x , x ) ); +( WITH x AS ( WITH x AS ( SELECT 1.000000 ) SELECT ( REPEAT ( ( json_normalize ( ' -1' ) ) , 357 ) ) x ) SELECT x FROM x WHERE x IN ( x , x ) ) +-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0-1.0E0 +# +# MDEV-37640: Crash in JSON_KEYS +# +SELECT JSON_SET('{"c":4}', '$.a', 5) AS x HAVING (x IN (JSON_KEYS(x), ',')); +x # End of 10.11 Test diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index b826f66ed85d0..04bf79a10a0e3 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -2032,4 +2032,16 @@ COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz; SELECT JSON_VALUE('{"a":[1,2]}', '$.a[*]'); +--echo # +--echo # MDEV-37640: Crash at String::append with json_normalize +--echo # + +SELECT ( WITH x AS ( WITH x AS ( SELECT 1.000000 ) SELECT ( REPEAT ( ( json_normalize ( ' -1' ) ) , 357 ) ) x ) SELECT x FROM x WHERE x IN ( x , x ) ); + +--echo # +--echo # MDEV-37640: Crash in JSON_KEYS +--echo # + +SELECT JSON_SET('{"c":4}', '$.a', 5) AS x HAVING (x IN (JSON_KEYS(x), ',')); + --echo # End of 10.11 Test diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 43d5460119670..4ed331d367d7e 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -3828,6 +3828,7 @@ String *Item_func_json_keys::val_str(String *str) goto null_return; str->length(0); + str->set_charset(collation.collation); if (str->append('[')) goto err_return; /* Out of memory. */ /* Parse the OBJECT collecting the keys. */ @@ -4514,6 +4515,7 @@ String *Item_func_json_normalize::val_str(String *buf) } buf->length(0); + buf->set_charset(collation.collation); if (buf->append(normalized_json.str, normalized_json.length)) { null_value= 1;