Commit 3d9d0e77 authored by Nisha Gopalakrishnan's avatar Nisha Gopalakrishnan

BUG#11757250: REPLACE(...) INSIDE A STORED PROCEDURE.

Analysis:
--------

REPLACE operation provides incorrect output when
user variable is supplied as an argument and there
are multiple rows on which the operation is performed.

Consider the example below:

SET @var='(( 00000000 ++ 00000000 ))';
SELECT REPLACE(@var, '00000000', table_name) AS a FROM
INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='mysql';

Invalid output:
  +---------------------------------------+
  | REPLACE(@var, '00000000', TABLE_NAME) |
  +---------------------------------------+
  | (( columns_priv ++ columns_priv ))    |
  | (( columns_priv ++ columns_priv ))    |
      ......
      ......
  | (( columns_priv ++ columns_priv ))    |
  | (( columns_priv ++ columns_priv ))    |
  | (( columns_priv ++ columns_priv ))    |
  +---------------------------------------+

The user argument supplied as the string to REPLACE
operation is overwritten after the first iteration
to '(( columns_priv ++ columns_priv ))'.
The overwritten string after the first iteration
is used for the subsequent REPLACE iteration. Since
the pattern string is not found, it returns invalid
output as mentioned above.

Fix:
---
If the Alloced_length is zero, realloc() and create a
copy of the string which is then used for the REPLACE
operation for every iteration.
parent 01094a4b
...@@ -761,7 +761,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) ...@@ -761,7 +761,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
{ {
if (from->Alloced_length >= from_length) if (from->Alloced_length >= from_length)
return from; return from;
if (from->alloced || !to || from == to) if ((from->alloced && (from->Alloced_length != 0)) || !to || from == to)
{ {
(void) from->realloc(from_length); (void) from->realloc(from_length);
return from; return from;
......
...@@ -796,7 +796,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) ...@@ -796,7 +796,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
{ {
if (from->Alloced_length >= from_length) if (from->Alloced_length >= from_length)
return from; return from;
if (from->alloced || !to || from == to) if ((from->alloced && (from->Alloced_length != 0)) || !to || from == to)
{ {
(void) from->realloc(from_length); (void) from->realloc(from_length);
return from; return from;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment