summaryrefslogtreecommitdiff
path: root/sql/sql_prepare.cc
diff options
context:
space:
mode:
authorDavi Arnaut <Davi.Arnaut@Sun.COM>2010-06-28 12:21:28 -0300
committerDavi Arnaut <Davi.Arnaut@Sun.COM>2010-06-28 12:21:28 -0300
commite42d90850c6599a1ec5800cc251a345cc34b92b0 (patch)
tree3dd60cea96ac5885f0651a8e47675e55346ed5c2 /sql/sql_prepare.cc
parent609e65ba54505531f228983912155de10750a3da (diff)
downloadmariadb-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.cc28
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 */
}