Commit 827b049e authored by tmokmss's avatar tmokmss Committed by Nikita Malyavin

MDEV-18873 Server crashes in Compare_identifiers::operator or in...

MDEV-18873 Server crashes in Compare_identifiers::operator or in my_strcasecmp_utf8 upon ADD PERIOD IF NOT EXISTS with empty name

empty identifier specified as `` ends up with a NULL LEX_CSTRING::str in lexer.
This is not considered correct in upper layers, for example in Compare_identifiers::operator().
Empty column name is usually avoided by a check_column_name() call while parsing,
and period name matches the column name completely.
Hence, this fix uses the mentioned call for verification, too.
parent 851058a3
...@@ -190,3 +190,17 @@ alter table t1 add primary key(x, s, e); ...@@ -190,3 +190,17 @@ alter table t1 add primary key(x, s, e);
ERROR 23000: Duplicate entry '1-2020-03-01-2020-03-02' for key 'PRIMARY' ERROR 23000: Duplicate entry '1-2020-03-01-2020-03-02' for key 'PRIMARY'
alter table t1 add system versioning; alter table t1 add system versioning;
drop table t1; drop table t1;
#
# MDEV-18873 Server crashes in Compare_identifiers::operator or in
# my_strcasecmp_utf8 upon ADD PERIOD IF NOT EXISTS with empty name
#
alter table t add period if not exists for `` (s,e);
ERROR 42000: Incorrect column name ''
create table t(s DATE, e DATE);
alter table t add period if not exists for `` (s,e);
ERROR 42000: Incorrect column name ''
alter table t add period if not exists for ` ` (s,e);
ERROR 42000: Incorrect column name ' '
create table t2 (period for `` (s,e)) select * from t;
ERROR 42000: Incorrect column name ''
drop table t;
...@@ -151,3 +151,26 @@ alter table t1 add system versioning; ...@@ -151,3 +151,26 @@ alter table t1 add system versioning;
# cleanup # cleanup
drop table t1; drop table t1;
--echo #
--echo # MDEV-18873 Server crashes in Compare_identifiers::operator or in
--echo # my_strcasecmp_utf8 upon ADD PERIOD IF NOT EXISTS with empty name
--echo #
# When there is no table defined.
--error ER_WRONG_COLUMN_NAME
alter table t add period if not exists for `` (s,e);
# When there is an actual table.
create table t(s DATE, e DATE);
--error ER_WRONG_COLUMN_NAME
alter table t add period if not exists for `` (s,e);
# When the last character is space
--error ER_WRONG_COLUMN_NAME
alter table t add period if not exists for ` ` (s,e);
# Create table with an empty period name
--error ER_WRONG_COLUMN_NAME
create table t2 (period for `` (s,e)) select * from t;
drop table t;
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "sql_tvc.h" #include "sql_tvc.h"
#include "item.h" #include "item.h"
#include "sql_schema.h" #include "sql_schema.h"
#include "table.h"
/* Used for flags of nesting constructs */ /* Used for flags of nesting constructs */
#define SELECT_NESTING_MAP_SIZE 64 #define SELECT_NESTING_MAP_SIZE 64
...@@ -4449,6 +4450,11 @@ struct LEX: public Query_tables_list ...@@ -4449,6 +4450,11 @@ struct LEX: public Query_tables_list
int add_period(Lex_ident name, Lex_ident_sys_st start, Lex_ident_sys_st end) int add_period(Lex_ident name, Lex_ident_sys_st start, Lex_ident_sys_st end)
{ {
if (check_period_name(name.str)) {
my_error(ER_WRONG_COLUMN_NAME, MYF(0), name.str);
return 1;
}
if (lex_string_cmp(system_charset_info, &start, &end) == 0) if (lex_string_cmp(system_charset_info, &start, &end) == 0)
{ {
my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), start.str); my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), start.str);
......
...@@ -4918,6 +4918,12 @@ bool check_column_name(const char *name) ...@@ -4918,6 +4918,12 @@ bool check_column_name(const char *name)
} }
bool check_period_name(const char *name)
{
return check_column_name(name);
}
/** /**
Checks whether a table is intact. Should be done *just* after the table has Checks whether a table is intact. Should be done *just* after the table has
been opened. been opened.
......
...@@ -3231,6 +3231,7 @@ void open_table_error(TABLE_SHARE *share, enum open_frm_error error, ...@@ -3231,6 +3231,7 @@ void open_table_error(TABLE_SHARE *share, enum open_frm_error error,
void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);
bool check_db_name(LEX_STRING *db); bool check_db_name(LEX_STRING *db);
bool check_column_name(const char *name); bool check_column_name(const char *name);
bool check_period_name(const char *name);
bool check_table_name(const char *name, size_t length, bool check_for_path_chars); bool check_table_name(const char *name, size_t length, bool check_for_path_chars);
int rename_file_ext(const char * from,const char * to,const char * ext); int rename_file_ext(const char * from,const char * to,const char * ext);
char *get_field(MEM_ROOT *mem, Field *field); char *get_field(MEM_ROOT *mem, Field *field);
......
...@@ -39,6 +39,8 @@ struct Compare_identifiers ...@@ -39,6 +39,8 @@ struct Compare_identifiers
{ {
int operator()(const LEX_CSTRING& a, const LEX_CSTRING& b) const int operator()(const LEX_CSTRING& a, const LEX_CSTRING& b) const
{ {
DBUG_ASSERT(a.str != NULL);
DBUG_ASSERT(b.str != NULL);
DBUG_ASSERT(a.str[a.length] == 0); DBUG_ASSERT(a.str[a.length] == 0);
DBUG_ASSERT(b.str[b.length] == 0); DBUG_ASSERT(b.str[b.length] == 0);
return my_strcasecmp(system_charset_info, a.str, b.str); return my_strcasecmp(system_charset_info, a.str, b.str);
......
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