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.
This commit is contained in:
Nisha Gopalakrishnan 2013-01-12 11:13:37 +05:30
parent 01094a4b13
commit 3d9d0e7766
2 changed files with 2 additions and 2 deletions

View File

@ -761,7 +761,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
{
if (from->Alloced_length >= from_length)
return from;
if (from->alloced || !to || from == to)
if ((from->alloced && (from->Alloced_length != 0)) || !to || from == to)
{
(void) from->realloc(from_length);
return from;

View File

@ -796,7 +796,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
{
if (from->Alloced_length >= from_length)
return from;
if (from->alloced || !to || from == to)
if ((from->alloced && (from->Alloced_length != 0)) || !to || from == to)
{
(void) from->realloc(from_length);
return from;