Skip to content

Commit

Permalink
MDEV-20261 NULL passed to String::eq, SEGV, server crash, regression …
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
abarkov committed May 12, 2020
1 parent db537a8 commit 9f20968
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
16 changes: 14 additions & 2 deletions sql/item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3477,8 +3477,20 @@ bool Item_basic_value::eq(const Item *item, bool binary_cmp) const
(h0= type_handler())->type_handler_for_comparison() ==
(h1= item->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() &&
h0->Item_const_eq(c0, c1, binary_cmp);
h1->cast_to_int_type_handler()->type_handler_for_comparison();
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",
push_warning_printf(current_thd,
Sql_condition::WARN_LEVEL_NOTE,
Expand Down
48 changes: 48 additions & 0 deletions tests/mysql_client_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -20886,6 +20886,53 @@ static void test_explain_meta()
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[]= {
{ "disable_query_logs", disable_query_logs },
{ "test_view_sp_list_fields", test_view_sp_list_fields },
Expand Down Expand Up @@ -21179,6 +21226,7 @@ static struct my_tests_st my_tests[]= {
#endif
{ "test_explain_meta", test_explain_meta },
{ "test_mdev18408", test_mdev18408 },
{ "test_mdev20261", test_mdev20261 },
{ 0, 0 }
};

Expand Down

0 comments on commit 9f20968

Please sign in to comment.