1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-35393 ASAN unknown-crash in Field_varstring::reset when inserting NULL value to a table with filename charset

Also fixes
MDEV-35392 Assertion `!__asan_region_is_poisoned((vo id*) dest,templ->mysql_col_len)' failed in void row_sel_field_store_in_mysql_format_func(byte *, const mysql_row_templ_t *, const byte *, ulint)

Conversion from CHAR to VARCHAR must be done before the call
for create_length_to_internal_length_string().
Moving the conversion code from Column_definition::prepare_blob_field()
to Column_definition::prepare_stage1_string().
This commit is contained in:
Alexander Barkov
2024-11-13 16:38:45 +04:00
parent 8e1cf078a0
commit 3b20045071
5 changed files with 98 additions and 27 deletions

View File

@@ -2307,6 +2307,34 @@ bool Column_definition::prepare_stage1_string(THD *thd,
handler *file,
ulonglong table_flags)
{
if (real_field_type() == FIELD_TYPE_STRING &&
length*charset->mbmaxlen > 1024)
{
DBUG_ASSERT(charset->mbmaxlen > 4);
/*
Convert long CHAR columns to VARCHAR.
CHAR has an octet length limit of 1024 bytes.
The code in Binlog_type_info_fixed_string::Binlog_type_info_fixed_string
relies on this limit. If octet length of a CHAR column is greater
than 1024, then it cannot write its metadata to binlog properly.
In case of the filename character set with mbmaxlen=5,
the maximum possible character length is 1024/5=204 characters.
Upgrade to VARCHAR if octet length is greater than 1024.
*/
char warn_buff[MYSQL_ERRMSG_SIZE];
if (thd->is_strict_mode())
{
my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name.str,
static_cast<ulong>(1024 / charset->mbmaxlen));
return true;
}
set_handler(&type_handler_varchar);
my_snprintf(warn_buff, sizeof(warn_buff), ER_THD(thd, ER_AUTO_CONVERT),
field_name.str, "CHAR", "VARCHAR");
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_AUTO_CONVERT,
warn_buff);
}
create_length_to_internal_length_string();
if (prepare_blob_field(thd))
return true;
@@ -3779,33 +3807,6 @@ bool Column_definition::prepare_blob_field(THD *thd)
{
DBUG_ENTER("Column_definition::prepare_blob_field");
if (real_field_type() == FIELD_TYPE_STRING && length > 1024)
{
DBUG_ASSERT(charset->mbmaxlen > 4);
/*
Convert long CHAR columns to VARCHAR.
CHAR has an octet length limit of 1024 bytes.
The code in Binlog_type_info_fixed_string::Binlog_type_info_fixed_string
relies on this limit. If octet length of a CHAR column is greater
than 1024, then it cannot write its metadata to binlog properly.
In case of the filename character set with mbmaxlen=5,
the maximum possible character length is 1024/5=204 characters.
Upgrade to VARCHAR if octet length is greater than 1024.
*/
char warn_buff[MYSQL_ERRMSG_SIZE];
if (thd->is_strict_mode())
{
my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name.str,
static_cast<ulong>(1024 / charset->mbmaxlen));
DBUG_RETURN(1);
}
set_handler(&type_handler_varchar);
my_snprintf(warn_buff, sizeof(warn_buff), ER_THD(thd, ER_AUTO_CONVERT),
field_name.str, "CHAR", "VARCHAR");
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_AUTO_CONVERT,
warn_buff);
}
if (length > MAX_FIELD_VARCHARLENGTH && !(flags & BLOB_FLAG))
{
/* Convert long VARCHAR columns to TEXT or BLOB */