diff options
author | Chaithra Gopalareddy <chaithra.gopalareddy@oracle.com> | 2013-05-10 19:18:21 +0530 |
---|---|---|
committer | Chaithra Gopalareddy <chaithra.gopalareddy@oracle.com> | 2013-05-10 19:18:21 +0530 |
commit | 07ef11b2cce540ccc09cb6ef8cf3d080a1c28926 (patch) | |
tree | db11819a163b702f380e02bc410e0d0d167354d2 /sql/sql_select.cc | |
parent | 3df10469a211e9ec7b33c740018d01d2c9150bbb (diff) | |
download | mariadb-git-07ef11b2cce540ccc09cb6ef8cf3d080a1c28926.tar.gz |
Bug#16119355:PREPARED STATEMENT: READ OF FREED MEMORY WITH STRING CONVERSION FUNCTIONS
Reverting fix for Bug#16119355 in 5.1 as this needs two patches
from 5.5+ to work for a certain case
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 104 |
1 files changed, 40 insertions, 64 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fabf2c81cc1..7b1a8cf9e82 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -15779,88 +15779,64 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, res_selected_fields.empty(); res_all_fields.empty(); - uint border= all_fields.elements - elements; - for (uint i= 0; (item= it++); i++) + uint i, border= all_fields.elements - elements; + for (i= 0; (item= it++); i++) { Field *field; - if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) + + if ((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) || + (item->type() == Item::FUNC_ITEM && + ((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC)) item_field= item; - else if (item->type() == Item::FIELD_ITEM) - item_field= item->get_tmp_table_item(thd); - else if (item->type() == Item::FUNC_ITEM && - ((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC) + else { - field= item->get_tmp_table_field(); - if( field != NULL) + if (item->type() == Item::FIELD_ITEM) { - /* - Replace "@:=<expression>" with "@:=<tmp table column>". Otherwise, we - would re-evaluate <expression>, and if expression were a subquery, this - would access already-unlocked tables. - */ - Item_func_set_user_var* suv= - new Item_func_set_user_var(thd, (Item_func_set_user_var*) item); - Item_field *new_field= new Item_field(field); - if (!suv || !new_field) - DBUG_RETURN(true); // Fatal error - /* - We are replacing the argument of Item_func_set_user_var after its value - has been read. The argument's null_value should be set by now, so we - must set it explicitly for the replacement argument since the null_value - may be read without any preceeding call to val_*(). - */ - new_field->update_null_value(); - List<Item> list; - list.push_back(new_field); - suv->set_arguments(list); - item_field= suv; + item_field= item->get_tmp_table_item(thd); } - else - item_field= item; - } - else if ((field= item->get_tmp_table_field())) - { - if (item->type() == Item::SUM_FUNC_ITEM && field->table->group) - item_field= ((Item_sum*) item)->result_item(field); - else - item_field= (Item*) new Item_field(field); - if (!item_field) - DBUG_RETURN(true); // Fatal error - - if (item->real_item()->type() != Item::FIELD_ITEM) - field->orig_table= 0; - item_field->name= item->name; - if (item->type() == Item::REF_ITEM) + else if ((field= item->get_tmp_table_field())) { - Item_field *ifield= (Item_field *) item_field; - Item_ref *iref= (Item_ref *) item; - ifield->table_name= iref->table_name; - ifield->db_name= iref->db_name; - } + if (item->type() == Item::SUM_FUNC_ITEM && field->table->group) + item_field= ((Item_sum*) item)->result_item(field); + else + item_field= (Item*) new Item_field(field); + if (!item_field) + DBUG_RETURN(TRUE); // Fatal error + + if (item->real_item()->type() != Item::FIELD_ITEM) + field->orig_table= 0; + item_field->name= item->name; + if (item->type() == Item::REF_ITEM) + { + Item_field *ifield= (Item_field *) item_field; + Item_ref *iref= (Item_ref *) item; + ifield->table_name= iref->table_name; + ifield->db_name= iref->db_name; + } #ifndef DBUG_OFF - if (!item_field->name) - { - char buff[256]; - String str(buff,sizeof(buff),&my_charset_bin); - str.length(0); - item->print(&str, QT_ORDINARY); - item_field->name= sql_strmake(str.ptr(),str.length()); - } + if (!item_field->name) + { + char buff[256]; + String str(buff,sizeof(buff),&my_charset_bin); + str.length(0); + item->print(&str, QT_ORDINARY); + item_field->name= sql_strmake(str.ptr(),str.length()); + } #endif + } + else + item_field= item; } - else - item_field= item; - res_all_fields.push_back(item_field); ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]= item_field; } List_iterator_fast<Item> itr(res_all_fields); - for (uint i= 0; i < border; i++) + for (i= 0; i < border; i++) itr++; itr.sublist(res_selected_fields, elements); - DBUG_RETURN(false); + DBUG_RETURN(FALSE); } |