summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRucha Deodhar <rucha.deodhar@mariadb.com>2020-06-24 13:59:26 +0530
committerRucha Deodhar <rucha.deodhar@mariadb.com>2020-06-24 15:14:25 +0530
commit4c2cde1bef1533dd989cb6a37c482c3437d66403 (patch)
tree743e9cf69fd224d89ff5541ceee6e51378b50233
parenteba918977793f0995d2f4f7707fc5dd891da4064 (diff)
downloadmariadb-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.h4
-rw-r--r--mysql-test/r/cte_nonrecursive.result21
-rw-r--r--mysql-test/t/cte_nonrecursive.test32
-rw-r--r--sql/sql_base.cc4
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;