summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2005-10-19 14:54:54 +0200
committerunknown <pem@mysql.com>2005-10-19 14:54:54 +0200
commita7f4882a43d8db061c2241438635fb13fc1c0d37 (patch)
treeeee9b75406cb564b8e00f309c9c00257e8fab4bb /sql/sp_head.cc
parentc30d1cfd9007e5e43c916fa1fd660b706e8d9c20 (diff)
downloadmariadb-git-a7f4882a43d8db061c2241438635fb13fc1c0d37.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. mysql-test/r/sp.result: New test case for BUG#13941. mysql-test/t/sp.test: New test case for BUG#13941. sql/sp_head.cc: Copy the string when evaluating some string functions (e.g. "replace" and "ifnull") to avoid using a dangling pointer.
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);