From 07767edcce4709b42bae5d3d9ca7be9ceacb95da Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 28 Jun 2010 12:21:28 -0300 Subject: Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run The problem was that a user could supply supply data in chunks via the COM_STMT_SEND_LONG_DATA command to prepared statement parameter other than of type TEXT or BLOB. This posed a problem since other parameter types aren't setup to handle long data, which would lead to a crash when attempting to use the supplied data. Given that long data can be supplied at any stage of a prepared statement, coupled with the fact that the type of a parameter marker might change between consecutive executions, the solution is to validate at execution time each parameter marker for which a data stream was provided. If the parameter type is not TEXT or BLOB (that is, if the type is not able to handle a data stream), a error is returned. --- sql/sql_prepare.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'sql/sql_prepare.cc') diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 06f77f9689c..c2fecd63777 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -674,6 +674,18 @@ static void setup_one_conversion_function(THD *thd, Item_param *param, } #ifndef EMBEDDED_LIBRARY + +/** + Check whether this parameter data type is compatible with long data. + Used to detect whether a long data stream has been supplied to a + incompatible data type. +*/ +inline bool is_param_long_data_type(Item_param *param) +{ + return ((param->param_type >= MYSQL_TYPE_TINY_BLOB) && + (param->param_type <= MYSQL_TYPE_STRING)); +} + /* Routines to assign parameters from data supplied by the client. @@ -737,6 +749,14 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array, DBUG_RETURN(1); } } + /* + A long data stream was supplied for this parameter marker. + This was done after prepare, prior to providing a placeholder + type (the types are supplied at execute). Check that the + supplied type of placeholder can accept a data stream. + */ + else if (!is_param_long_data_type(param)) + DBUG_RETURN(1); res= param->query_val_str(&str); if (param->convert_str_value(thd)) DBUG_RETURN(1); /* out of memory */ @@ -775,6 +795,14 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array, DBUG_RETURN(1); } } + /* + A long data stream was supplied for this parameter marker. + This was done after prepare, prior to providing a placeholder + type (the types are supplied at execute). Check that the + supplied type of placeholder can accept a data stream. + */ + else if (is_param_long_data_type(param)) + DBUG_RETURN(1); if (param->convert_str_value(stmt->thd)) DBUG_RETURN(1); /* out of memory */ } -- cgit v1.2.1