diff options
author | unknown <mats@romeo.(none)> | 2006-12-05 10:46:03 +0100 |
---|---|---|
committer | unknown <mats@romeo.(none)> | 2006-12-05 10:46:03 +0100 |
commit | 8372e7725f0d0fed811b1fe07308d9386a13f667 (patch) | |
tree | c7b5012b7bab4c808f1bdbd7e09c51510c19585e /sql/log_event.cc | |
parent | b0e490e83708926aab0400b211d5cd5ade5087c5 (diff) | |
download | mariadb-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.cc | 13 |
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 |