mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-39049: Memory corruption & crash in check_key_in_list upon using
JSON_KEYS after modifying character set name/collation Analysis: Buffer overflow crashes and empty key duplication in check_key_in_list. Fix: Checking result buffer validity prevents segmentation faults on empty strings and malformed inputs while preserving correct key matching behavior.
This commit is contained in:
@@ -3091,11 +3091,13 @@ DROP TABLE t;
|
||||
# using JSON_KEYS after modifying character set name/collation
|
||||
#
|
||||
SET SESSION character_set_database=utf32;
|
||||
SET CHARSET DEFAULT;
|
||||
SELECT JSON_KEYS('{"":');
|
||||
JSON_KEYS('{"":')
|
||||
SELECT JSON_KEYS ('{"S":-1.0,"D": {"o":,"a": }}');
|
||||
JSON_KEYS ('{"S":-1.0,"D": {"o":,"a": }}')
|
||||
NULL
|
||||
Warnings:
|
||||
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_keys'
|
||||
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_keys' at position 25
|
||||
SELECT JSON_KEYS('{"":1, "k2":2, "":3, "k2":4 }');
|
||||
JSON_KEYS('{"":1, "k2":2, "":3, "k2":4 }')
|
||||
["", "k2"]
|
||||
SET SESSION character_set_database= default;
|
||||
# End of 10.11 Test
|
||||
|
||||
@@ -2189,9 +2189,8 @@ DROP TABLE t;
|
||||
--echo # MDEV-39049: Memory corruption & crash in check_key_in_list upon
|
||||
--echo # using JSON_KEYS after modifying character set name/collation
|
||||
--echo #
|
||||
|
||||
SET SESSION character_set_database=utf32;
|
||||
SET CHARSET DEFAULT;
|
||||
SELECT JSON_KEYS('{"":');
|
||||
SELECT JSON_KEYS ('{"S":-1.0,"D": {"o":,"a": }}');
|
||||
SELECT JSON_KEYS('{"":1, "k2":2, "":3, "k2":4 }');
|
||||
SET SESSION character_set_database= default;
|
||||
--echo # End of 10.11 Test
|
||||
|
||||
@@ -3882,31 +3882,32 @@ static int check_key_in_list(String *res,
|
||||
{
|
||||
const uchar *c, *end;
|
||||
|
||||
if (!key_len)
|
||||
if (!res || res->length() < 2)
|
||||
return 0;
|
||||
|
||||
c= (const uchar *) res->ptr() + 2; /* beginning '["' */
|
||||
end= (const uchar *) res->end() - 1; /* ending '"' */
|
||||
c= (const uchar *) res->ptr() + 1;
|
||||
end= (const uchar *) res->end();
|
||||
|
||||
while (c < end)
|
||||
{
|
||||
int n_char;
|
||||
for (n_char=0; c[n_char] != '"' && n_char < key_len; n_char++)
|
||||
while (c < end && *c != '"')
|
||||
c++;
|
||||
if (c >= end)
|
||||
break;
|
||||
c++;
|
||||
|
||||
const uchar *key_start= c;
|
||||
int n_char= 0;
|
||||
while (c + n_char < end && c[n_char] != '"')
|
||||
{
|
||||
if (c[n_char] != key[n_char])
|
||||
break;
|
||||
n_char++;
|
||||
}
|
||||
if (c[n_char] == '"')
|
||||
{
|
||||
if (n_char == key_len)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (c[n_char] != '"')
|
||||
n_char++;
|
||||
}
|
||||
c+= n_char + 4; /* skip ', "' */
|
||||
|
||||
if (n_char == key_len &&
|
||||
(key_len == 0 || memcmp(key_start, key, key_len) == 0))
|
||||
return 1;
|
||||
|
||||
c+= n_char + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user