diff options
author | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2010-06-28 12:21:28 -0300 |
---|---|---|
committer | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2010-06-28 12:21:28 -0300 |
commit | e42d90850c6599a1ec5800cc251a345cc34b92b0 (patch) | |
tree | 3dd60cea96ac5885f0651a8e47675e55346ed5c2 /sql/sql_prepare.cc | |
parent | 609e65ba54505531f228983912155de10750a3da (diff) | |
download | mariadb-git-e42d90850c6599a1ec5800cc251a345cc34b92b0.tar.gz |
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:
Before converting the parameter data stream, check the type
compatibility.
tests/mysql_client_test.c:
Add test case.
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r-- | sql/sql_prepare.cc | 28 |
1 files changed, 28 insertions, 0 deletions
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 */ } |