diff options
author | pem@mysql.com <> | 2005-10-19 14:54:54 +0200 |
---|---|---|
committer | pem@mysql.com <> | 2005-10-19 14:54:54 +0200 |
commit | ca5e435f82d550aa9d303a51d704f7cdb2a99583 (patch) | |
tree | eee9b75406cb564b8e00f309c9c00257e8fab4bb /sql/sp_head.cc | |
parent | a9d1a37477729d78ac679c469f06bbc38eae4560 (diff) | |
download | mariadb-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.cc | 15 |
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); |