Commit a9a2ceae authored by Georgi Kodinov's avatar Georgi Kodinov

Bug #51850: crash/memory overlap when using load data infile and set

  col equal to itself!

There's no need to copy the value of a field into itself.
While generally harmless (except for some performance penalties)
it may be dangerous when the copy code doesn't expect this.
Fixed by checking if the source field is the same as the destination
field before copying the data.
Note that we must preserve the order of assignment of the null 
flags (hence the null_value assignment addition).
parent a3541878
...@@ -484,4 +484,15 @@ SET character_set_filesystem=default; ...@@ -484,4 +484,15 @@ SET character_set_filesystem=default;
select @@character_set_filesystem; select @@character_set_filesystem;
@@character_set_filesystem @@character_set_filesystem
binary binary
#
# Bug #51850: crash/memory overlap when using load data infile and set
# col equal to itself!
#
CREATE TABLE t1(col0 LONGBLOB);
SELECT 'test' INTO OUTFILE 't1.txt';
LOAD DATA INFILE 't1.txt' IGNORE INTO TABLE t1 SET col0=col0;
SELECT * FROM t1;
col0
test
DROP TABLE t1;
End of 5.1 tests End of 5.1 tests
...@@ -532,5 +532,19 @@ SET character_set_filesystem=default; ...@@ -532,5 +532,19 @@ SET character_set_filesystem=default;
select @@character_set_filesystem; select @@character_set_filesystem;
--echo #
--echo # Bug #51850: crash/memory overlap when using load data infile and set
--echo # col equal to itself!
--echo #
CREATE TABLE t1(col0 LONGBLOB);
SELECT 'test' INTO OUTFILE 't1.txt';
LOAD DATA INFILE 't1.txt' IGNORE INTO TABLE t1 SET col0=col0;
SELECT * FROM t1;
DROP TABLE t1;
let $MYSQLD_DATADIR= `select @@datadir`;
remove_file $MYSQLD_DATADIR/test/t1.txt;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -5063,14 +5063,22 @@ int Item_field::save_in_field(Field *to, bool no_conversions) ...@@ -5063,14 +5063,22 @@ int Item_field::save_in_field(Field *to, bool no_conversions)
if (result_field->is_null()) if (result_field->is_null())
{ {
null_value=1; null_value=1;
res= set_field_to_null_with_conversions(to, no_conversions); return set_field_to_null_with_conversions(to, no_conversions);
} }
else
{
to->set_notnull(); to->set_notnull();
res= field_conv(to,result_field);
/*
If we're setting the same field as the one we're reading from there's
nothing to do. This can happen in 'SET x = x' type of scenarios.
*/
if (to == result_field)
{
null_value=0; null_value=0;
return 0;
} }
res= field_conv(to,result_field);
null_value=0;
return res; return res;
} }
......
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