diff options
author | tmokmss <tomookam@live.jp> | 2022-06-05 08:04:18 +0000 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2022-08-26 12:40:58 +0300 |
commit | 827b049e1e7df204feb744a270b4dca619a61de1 (patch) | |
tree | 607c8f72697c91d696c7a931af1698d545e57f00 | |
parent | 851058a3e6f40cd2714762916235ebe93fc594b5 (diff) | |
download | mariadb-git-827b049e1e7df204feb744a270b4dca619a61de1.tar.gz |
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.
-rw-r--r-- | mysql-test/suite/period/r/alter.result | 14 | ||||
-rw-r--r-- | mysql-test/suite/period/t/alter.test | 23 | ||||
-rw-r--r-- | sql/sql_lex.h | 6 | ||||
-rw-r--r-- | sql/table.cc | 6 | ||||
-rw-r--r-- | sql/table.h | 1 | ||||
-rw-r--r-- | sql/vers_string.h | 2 |
6 files changed, 52 insertions, 0 deletions
diff --git a/mysql-test/suite/period/r/alter.result b/mysql-test/suite/period/r/alter.result index a6466c8944b..875dab93b68 100644 --- a/mysql-test/suite/period/r/alter.result +++ b/mysql-test/suite/period/r/alter.result @@ -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' alter table t1 add system versioning; 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; diff --git a/mysql-test/suite/period/t/alter.test b/mysql-test/suite/period/t/alter.test index 3fa3c5c87d5..2a82f74b670 100644 --- a/mysql-test/suite/period/t/alter.test +++ b/mysql-test/suite/period/t/alter.test @@ -151,3 +151,26 @@ alter table t1 add system versioning; # cleanup 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; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index be41b45c335..976d1b79cad 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -33,6 +33,7 @@ #include "sql_tvc.h" #include "item.h" #include "sql_schema.h" +#include "table.h" /* Used for flags of nesting constructs */ #define SELECT_NESTING_MAP_SIZE 64 @@ -4449,6 +4450,11 @@ public: 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) { my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), start.str); diff --git a/sql/table.cc b/sql/table.cc index 7957f2da593..1a30809cde9 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -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 been opened. diff --git a/sql/table.h b/sql/table.h index c9503b54934..3f750e7b221 100644 --- a/sql/table.h +++ b/sql/table.h @@ -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); bool check_db_name(LEX_STRING *db); 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); int rename_file_ext(const char * from,const char * to,const char * ext); char *get_field(MEM_ROOT *mem, Field *field); diff --git a/sql/vers_string.h b/sql/vers_string.h index 2349cc0cac1..cfadc890dcd 100644 --- a/sql/vers_string.h +++ b/sql/vers_string.h @@ -39,6 +39,8 @@ struct Compare_identifiers { 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(b.str[b.length] == 0); return my_strcasecmp(system_charset_info, a.str, b.str); |