summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorpem@mysql.com <>2005-10-19 14:54:54 +0200
committerpem@mysql.com <>2005-10-19 14:54:54 +0200
commitca5e435f82d550aa9d303a51d704f7cdb2a99583 (patch)
treeeee9b75406cb564b8e00f309c9c00257e8fab4bb /sql/sp_head.cc
parenta9d1a37477729d78ac679c469f06bbc38eae4560 (diff)
downloadmariadb-git-ca5e435f82d550aa9d303a51d704f7cdb2a99583.tar.gz
Fixed BUG#13941: replace() string fuction behaves badly inside stored
procedure For some functions returning strings (like "replace" and "ifnull" - where val_str() is returning a pointer into one of the parameters) - we ended up with a dangling pointer after the new operator destroyed the reuse item in the eval function. A working, if not very elegant, solution is to simply copy the string in such cases.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc15
1 files changed, 15 insertions, 0 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 063c388702d..65e6a239242 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -293,6 +293,21 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type,
if (it == reuse)
DBUG_RETURN(it);
+ /*
+ For some functions, 's' is now pointing to an argument of the
+ function, which might be a local variable that it to be reused.
+ In this case, new(reuse, &rsize) below will call the destructor
+ and 's' ends up pointing to freed memory.
+ A somewhat ugly fix is to simply copy the string to our local one
+ (which is unused by most functions anyway), but only if 's' is
+ pointing somewhere else than to 'tmp' or 'it->str_value'.
+ */
+ if (reuse && s != &tmp && s != &it->str_value)
+ {
+ tmp.copy(s->c_ptr(), s->length(), it->collation.collation);
+ s= &tmp;
+ }
+
CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize)
Item_string(it->collation.collation),
use_callers_arena, &backup_arena);