diff options
author | Sergey Glukhov <sergey.glukhov@oracle.com> | 2013-03-14 11:11:17 +0300 |
---|---|---|
committer | Sergey Glukhov <sergey.glukhov@oracle.com> | 2013-03-14 11:11:17 +0300 |
commit | ca5caac14fe7c198ed5ed30aab915575414c6c25 (patch) | |
tree | 84d18c9efea59bc0df0eb2171e27b3c8807076f1 | |
parent | 77dd8193a02f4d1259829a98d1a25819a65a3d0c (diff) | |
download | mariadb-git-ca5caac14fe7c198ed5ed30aab915575414c6c25.tar.gz |
Bug#16075310 SERVER CRASH OR VALGRIND ERRORS IN ITEM_FUNC_GROUP_CONCAT::SETUP AND ::ADD
Item_func_group_concat::copy_or_same() creates a copy of original object.
It also creates a copy of ORDER structure because ORDER struct elements may
be modified in find_order_in_list() called from Item_func_group_concat::setup().
As ORDER copy is created using memcpy, ORDER::next elements point to original
ORDER structs. Thus find_order_in_list() called from EXECUTE stmt modifies
ordinal ORDER item pointers so they point to runtime items, these items are
freed after execution, so original ORDER structure becomes invalid.
The fix is to properly update ORDER::next fields so that they point to
new ORDER elements.
-rw-r--r-- | sql/item_sum.cc | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 40ac31918be..8bb5df719d3 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3041,7 +3041,14 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, tmp= (ORDER *)(order + arg_count_order); for (uint i= 0; i < arg_count_order; i++, tmp++) { - memcpy(tmp, item->order[i], sizeof(ORDER)); + /* + Compiler generated copy constructor is used to + to copy all the members of ORDER struct. + It's also necessary to update ORDER::next pointer + so that it points to new ORDER element. + */ + new (tmp) st_order(*(item->order[i])); + tmp->next= (i + 1 == arg_count_order) ? NULL : (tmp + 1); order[i]= tmp; } } |