summaryrefslogtreecommitdiff
path: root/sql/log_event.cc
diff options
context:
space:
mode:
authorunknown <mats@romeo.(none)>2006-12-05 10:46:03 +0100
committerunknown <mats@romeo.(none)>2006-12-05 10:46:03 +0100
commit8372e7725f0d0fed811b1fe07308d9386a13f667 (patch)
treec7b5012b7bab4c808f1bdbd7e09c51510c19585e /sql/log_event.cc
parentb0e490e83708926aab0400b211d5cd5ade5087c5 (diff)
downloadmariadb-git-8372e7725f0d0fed811b1fe07308d9386a13f667.tar.gz
BUG#24490 (segfault inside unpack_row at Field_bit_as_char::set_default()):
Field_bit::set_default() did not check the bit_len, hence used the undefined bit_ptr, causing a crash. The patch adds a check that bit_len > 0 before following the bit_ptr. mysql-test/extra/rpl_tests/rpl_row_tabledefs.test: Doing select using ORDER BY to prevent table-internal order from affecting the result. mysql-test/r/rpl_row_tabledefs_2myisam.result: Result change mysql-test/r/rpl_row_tabledefs_3innodb.result: Result change sql/field.cc: Checking bit_len before following the bit_ptr, since bit_ptr has no sensible value in the case that bit_len == 0. sql/field.h: Field_bit::set_default() used the bit_ptr, but it is undefined, hence causing a crash. In reality, the hierarchy order is not correct so added a TODO comment about refactoring. sql/log_event.cc: Code was manipulating bits for a FIELD_TYPE_BIT field without checking if the bit_len was > 0, hence using an undefined bit_ptr when the class was actually a Field_bit_as_char. mysql-test/t/rpl_row_tabledefs_3innodb-slave.opt: New BitKeeper file ``mysql-test/t/rpl_row_tabledefs_3innodb-slave.opt''
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r--sql/log_event.cc13
1 files changed, 8 insertions, 5 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 7bb4a72edfa..f5ddaf12d6d 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -6578,10 +6578,13 @@ copy_extra_record_fields(TABLE *table,
case FIELD_TYPE_BIT:
Field_bit *f= static_cast<Field_bit*>(*field_ptr);
- my_ptrdiff_t const offset= table->record[1] - table->record[0];
- uchar const bits=
- get_rec_bits(f->bit_ptr + offset, f->bit_ofs, f->bit_len);
- set_rec_bits(bits, f->bit_ptr, f->bit_ofs, f->bit_len);
+ if (f->bit_len > 0)
+ {
+ my_ptrdiff_t const offset= table->record[1] - table->record[0];
+ uchar const bits=
+ get_rec_bits(f->bit_ptr + offset, f->bit_ofs, f->bit_len);
+ set_rec_bits(bits, f->bit_ptr, f->bit_ofs, f->bit_len);
+ }
break;
}
}
@@ -6682,7 +6685,7 @@ replace_record(THD *thd, TABLE *table,
present on the master from table->record[1], if there are any.
*/
copy_extra_record_fields(table, master_reclength, master_fields);
-
+
/*
REPLACE is defined as either INSERT or DELETE + INSERT. If
possible, we can replace it with an UPDATE, but that will not