Commit eadd8788 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax

The crash happened because my_isalnum() does not support character
sets with mbminlen>1.

The value of "ft_boolean_syntax" is converted to utf8 in do_string_check().
So calling my_isalnum() is combination with "default_charset_info" was wrong.

Adding new parameters (size_t length, CHARSET_INFO *cs) to
ft_boolean_check_syntax_string() and passing self->charset(thd)
as the character set.
parent 9300b665
...@@ -90,7 +90,8 @@ void ft_free_stopwords(void); ...@@ -90,7 +90,8 @@ void ft_free_stopwords(void);
FT_INFO *ft_init_search(uint,void *, uint, uchar *, size_t, FT_INFO *ft_init_search(uint,void *, uint, uchar *, size_t,
CHARSET_INFO *, uchar *); CHARSET_INFO *, uchar *);
my_bool ft_boolean_check_syntax_string(const uchar *); my_bool ft_boolean_check_syntax_string(const uchar *, size_t length,
CHARSET_INFO *cs);
/* Internal symbols for fulltext between maria and MyISAM */ /* Internal symbols for fulltext between maria and MyISAM */
......
...@@ -8,3 +8,8 @@ character_set_server utf16 ...@@ -8,3 +8,8 @@ character_set_server utf16
SHOW VARIABLES LIKE 'ft_stopword_file'; SHOW VARIABLES LIKE 'ft_stopword_file';
Variable_name Value Variable_name Value
ft_stopword_file (built-in) ft_stopword_file (built-in)
#
# MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax
#
SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|';
SET GLOBAL ft_boolean_syntax=DEFAULT;
call mtr.add_suppression("'utf32' can not be used as client character set");
#
# MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax
#
SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|';
SET GLOBAL ft_boolean_syntax=DEFAULT;
...@@ -7,3 +7,10 @@ call mtr.add_suppression("'utf16' can not be used as client character set"); ...@@ -7,3 +7,10 @@ call mtr.add_suppression("'utf16' can not be used as client character set");
SHOW VARIABLES LIKE 'collation_server'; SHOW VARIABLES LIKE 'collation_server';
SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'character_set_server';
SHOW VARIABLES LIKE 'ft_stopword_file'; SHOW VARIABLES LIKE 'ft_stopword_file';
--echo #
--echo # MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax
--echo #
SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|';
SET GLOBAL ft_boolean_syntax=DEFAULT;
--character-set-server=utf32,latin1 --collation-server=utf32_general_ci
--source include/have_utf32.inc
call mtr.add_suppression("'utf32' can not be used as client character set");
--echo #
--echo # MDEV-23269 SIGSEGV in ft_boolean_check_syntax_string on setting ft_boolean_syntax
--echo #
SET GLOBAL ft_boolean_syntax='+ -><()~*:""&|';
SET GLOBAL ft_boolean_syntax=DEFAULT;
...@@ -9666,7 +9666,9 @@ static int get_options(int *argc_ptr, char ***argv_ptr) ...@@ -9666,7 +9666,9 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
if (global_system_variables.low_priority_updates) if (global_system_variables.low_priority_updates)
thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY; thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
if (ft_boolean_check_syntax_string((uchar*) ft_boolean_syntax)) if (ft_boolean_check_syntax_string((uchar*) ft_boolean_syntax,
strlen(ft_boolean_syntax),
system_charset_info))
{ {
sql_print_error("Invalid ft-boolean-syntax string: %s\n", sql_print_error("Invalid ft-boolean-syntax string: %s\n",
ft_boolean_syntax); ft_boolean_syntax);
......
...@@ -1022,7 +1022,9 @@ static Sys_var_ulong Sys_flush_time( ...@@ -1022,7 +1022,9 @@ static Sys_var_ulong Sys_flush_time(
static bool check_ftb_syntax(sys_var *self, THD *thd, set_var *var) static bool check_ftb_syntax(sys_var *self, THD *thd, set_var *var)
{ {
return ft_boolean_check_syntax_string((uchar*) return ft_boolean_check_syntax_string((uchar*)
(var->save_result.string_value.str)); (var->save_result.string_value.str),
var->save_result.string_value.length,
self->charset(thd));
} }
static bool query_cache_flush(sys_var *self, THD *thd, enum_var_type type) static bool query_cache_flush(sys_var *self, THD *thd, enum_var_type type)
{ {
......
...@@ -78,18 +78,25 @@ FT_WORD * ft_linearize(TREE *wtree, MEM_ROOT *mem_root) ...@@ -78,18 +78,25 @@ FT_WORD * ft_linearize(TREE *wtree, MEM_ROOT *mem_root)
DBUG_RETURN(wlist); DBUG_RETURN(wlist);
} }
my_bool ft_boolean_check_syntax_string(const uchar *str) my_bool ft_boolean_check_syntax_string(const uchar *str, size_t length,
CHARSET_INFO *cs)
{ {
uint i, j; uint i, j;
if (cs->mbminlen != 1)
{
DBUG_ASSERT(0);
return 1;
}
if (!str || if (!str ||
(strlen((char*) str)+1 != sizeof(DEFAULT_FTB_SYNTAX)) || (length + 1 != sizeof(DEFAULT_FTB_SYNTAX)) ||
(str[0] != ' ' && str[1] != ' ')) (str[0] != ' ' && str[1] != ' '))
return 1; return 1;
for (i=0; i<sizeof(DEFAULT_FTB_SYNTAX); i++) for (i=0; i<sizeof(DEFAULT_FTB_SYNTAX); i++)
{ {
/* limiting to 7-bit ascii only */ /* limiting to 7-bit ascii only */
if ((unsigned char)(str[i]) > 127 || my_isalnum(default_charset_info, str[i])) if ((unsigned char)(str[i]) > 127 || my_isalnum(cs, str[i]))
return 1; return 1;
for (j=0; j<i; j++) for (j=0; j<i; j++)
if (str[i] == str[j] && (i != 11 || j != 10)) if (str[i] == str[j] && (i != 11 || j != 10))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment