diff options
author | Rucha Deodhar <rucha.deodhar@mariadb.com> | 2020-06-24 13:59:26 +0530 |
---|---|---|
committer | Rucha Deodhar <rucha.deodhar@mariadb.com> | 2020-06-24 15:14:25 +0530 |
commit | 4c2cde1bef1533dd989cb6a37c482c3437d66403 (patch) | |
tree | 743e9cf69fd224d89ff5541ceee6e51378b50233 | |
parent | eba918977793f0995d2f4f7707fc5dd891da4064 (diff) | |
download | mariadb-git-bb-10.2-MDEV-20643.tar.gz |
MDEV-20643: Server crashes in find_table_in_list upon INSERT .. SELECT after dropping a databasebb-10.2-MDEV-20643
table->db is NULL, so strcmp() in find_tables_in_list() gets NULL in the
argument. So it crashes.
Fix: Using a safe_strcmp() function which compares two strings if they are
not null otherwise uses safe_str() to convert the NULL string into
empty string before comparing them.
-rw-r--r-- | include/m_string.h | 4 | ||||
-rw-r--r-- | mysql-test/r/cte_nonrecursive.result | 21 | ||||
-rw-r--r-- | mysql-test/t/cte_nonrecursive.test | 32 | ||||
-rw-r--r-- | sql/sql_base.cc | 4 |
4 files changed, 59 insertions, 2 deletions
diff --git a/include/m_string.h b/include/m_string.h index 2f609d5e29f..864962735f3 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -232,6 +232,10 @@ static inline char *safe_str(char *str) static inline const char *safe_str(const char *str) { return str ? str : ""; } +static inline int safe_strcmp(char *str1, const char *str2) +{ return ((str1 && str2) ? strcmp(str1, str2) : + strcmp(safe_str(str1), safe_str(str2))); } + static inline size_t safe_strlen(const char *str) { return str ? strlen(str) : 0; } diff --git a/mysql-test/r/cte_nonrecursive.result b/mysql-test/r/cte_nonrecursive.result index 746fcbcf051..ee92309b5ac 100644 --- a/mysql-test/r/cte_nonrecursive.result +++ b/mysql-test/r/cte_nonrecursive.result @@ -1690,4 +1690,25 @@ ERROR 3D000: No database selected DROP TABLE test.t; connection default; disconnect con1; +# +# MDEV-20643: Server crashes in find_table_in_list upon INSERT .. SELECT after dropping a database +# +CREATE TABLE t1 (a INT) ENGINE=MEMORY; +CREATE SCHEMA db; +CREATE PROCEDURE db.pr() SELECT * FROM test.t1; +connect con1,localhost,root,,test; +DROP DATABASE db; +connection default; +SELECT * FROM t1; +a +KILL 11; +CALL db.pr; +CREATE TABLE test.t2 LIKE test.t1 ; +INSERT test.t2 WITH cte AS ( SELECT * FROM test.t1 ) SELECT * FROM cte; +connection con1; +connection default; +DROP DATABASE IF EXISTS db; +Warnings: +Note 1008 Can't drop database 'db'; database doesn't exist +DROP TABLE IF EXISTS test.t1, test.t2; # End of 10.2 tests diff --git a/mysql-test/t/cte_nonrecursive.test b/mysql-test/t/cte_nonrecursive.test index 41a5b815bc7..c54f7d4e0e8 100644 --- a/mysql-test/t/cte_nonrecursive.test +++ b/mysql-test/t/cte_nonrecursive.test @@ -1201,4 +1201,36 @@ DROP TABLE test.t; --connection default --disconnect con1 +--echo # +--echo # MDEV-20643: Server crashes in find_table_in_list upon INSERT .. SELECT after dropping a database +--echo # +--source include/have_innodb.inc + +CREATE TABLE t1 (a INT) ENGINE=MEMORY; +CREATE SCHEMA db; +CREATE PROCEDURE db.pr() SELECT * FROM test.t1; + +--connect (con1,localhost,root,,test) +--let $con1_id= `SELECT CONNECTION_ID()` +--send + DROP DATABASE db; + +--connection default +SELECT * FROM t1; +--eval KILL $con1_id + +--error 0,ER_BAD_DB_ERROR,ER_SP_DOES_NOT_EXIST +CALL db.pr; +CREATE TABLE test.t2 LIKE test.t1 ; +INSERT test.t2 WITH cte AS ( SELECT * FROM test.t1 ) SELECT * FROM cte; + +# Partial cleanup +# (full cleanup is not always possible due to MDEV-20642) +--connection con1 +--error 0,2013 +--reap +--connection default +DROP DATABASE IF EXISTS db; +DROP TABLE IF EXISTS test.t1, test.t2; + --echo # End of 10.2 tests diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 436f753557e..0aff16e6147 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -939,8 +939,8 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, { for (; table; table= table->*link ) { - if (strcmp(table->db, db_name) == 0 && - strcmp(table->table_name, table_name) == 0) + if (safe_strcmp(table->db, db_name) == 0 && + safe_strcmp(table->table_name, table_name) == 0) break; } return table; |