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