mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
MDEV-20261 NULL passed to String::eq, SEGV, server crash, regression in 10.4
Type_handler_xxx::Item_const_eq() can handle only non-NULL values. The code in Item_basic_value::eq() did not take this into account. Adding a test to detect three different combinations: - Both values are NULLs, return true. - Only one value is NULL, return false. - Both values are not NULL, call Type_handler::Item_const_eq() to check equality.
This commit is contained in:
parent
db537a8372
commit
9f20968169
2 changed files with 62 additions and 2 deletions
16
sql/item.cc
16
sql/item.cc
|
@ -3477,8 +3477,20 @@ bool Item_basic_value::eq(const Item *item, bool binary_cmp) const
|
||||||
(h0= type_handler())->type_handler_for_comparison() ==
|
(h0= type_handler())->type_handler_for_comparison() ==
|
||||||
(h1= item->type_handler())->type_handler_for_comparison() &&
|
(h1= item->type_handler())->type_handler_for_comparison() &&
|
||||||
h0->cast_to_int_type_handler()->type_handler_for_comparison() ==
|
h0->cast_to_int_type_handler()->type_handler_for_comparison() ==
|
||||||
h1->cast_to_int_type_handler()->type_handler_for_comparison() &&
|
h1->cast_to_int_type_handler()->type_handler_for_comparison();
|
||||||
h0->Item_const_eq(c0, c1, binary_cmp);
|
if (res)
|
||||||
|
{
|
||||||
|
switch (c0->const_is_null() + c1->const_is_null()) {
|
||||||
|
case 2: // Two NULLs
|
||||||
|
res= true;
|
||||||
|
break;
|
||||||
|
case 1: // NULL and non-NULL
|
||||||
|
res= false;
|
||||||
|
break;
|
||||||
|
case 0: // Two non-NULLs
|
||||||
|
res= h0->Item_const_eq(c0, c1, binary_cmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
DBUG_EXECUTE_IF("Item_basic_value",
|
DBUG_EXECUTE_IF("Item_basic_value",
|
||||||
push_warning_printf(current_thd,
|
push_warning_printf(current_thd,
|
||||||
Sql_condition::WARN_LEVEL_NOTE,
|
Sql_condition::WARN_LEVEL_NOTE,
|
||||||
|
|
|
@ -20886,6 +20886,53 @@ static void test_explain_meta()
|
||||||
mct_close_log();
|
mct_close_log();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
MDEV-20261 NULL passed to String::eq, SEGV, server crash, regression in 10.4
|
||||||
|
*/
|
||||||
|
static void test_mdev20261()
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
MYSQL_STMT *stmt;
|
||||||
|
MYSQL_BIND param[1];
|
||||||
|
const char *query= "SELECT * FROM t1 WHERE f = ? OR f = 'foo'";
|
||||||
|
char val[]= "";
|
||||||
|
my_bool is_null= TRUE;
|
||||||
|
|
||||||
|
myheader("test_mdev20261");
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (f varchar(64)) ENGINE=MyISAM");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
stmt= mysql_stmt_init(mysql);
|
||||||
|
check_stmt(stmt);
|
||||||
|
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
|
||||||
|
verify_param_count(stmt, 1);
|
||||||
|
|
||||||
|
bzero((char*) param, sizeof(param));
|
||||||
|
|
||||||
|
param[0].buffer= &val;
|
||||||
|
param[0].buffer_type= MYSQL_TYPE_STRING;
|
||||||
|
param[0].is_null= &is_null;
|
||||||
|
|
||||||
|
rc= mysql_stmt_bind_param(stmt, param);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
|
||||||
|
rc= mysql_stmt_store_result(stmt);
|
||||||
|
check_execute(stmt, rc);
|
||||||
|
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE t1");
|
||||||
|
myquery(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct my_tests_st my_tests[]= {
|
static struct my_tests_st my_tests[]= {
|
||||||
{ "disable_query_logs", disable_query_logs },
|
{ "disable_query_logs", disable_query_logs },
|
||||||
{ "test_view_sp_list_fields", test_view_sp_list_fields },
|
{ "test_view_sp_list_fields", test_view_sp_list_fields },
|
||||||
|
@ -21179,6 +21226,7 @@ static struct my_tests_st my_tests[]= {
|
||||||
#endif
|
#endif
|
||||||
{ "test_explain_meta", test_explain_meta },
|
{ "test_explain_meta", test_explain_meta },
|
||||||
{ "test_mdev18408", test_mdev18408 },
|
{ "test_mdev18408", test_mdev18408 },
|
||||||
|
{ "test_mdev20261", test_mdev20261 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue