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 | 4924c61999cac4738f7f4a7422d600e0b7dcf3a3 (patch) | |
tree | c7b5012b7bab4c808f1bdbd7e09c51510c19585e /sql/field.cc | |
parent | 2138534c134c89eb68cf17a3c7534a3459c1ea5b (diff) | |
download | mariadb-git-4924c61999cac4738f7f4a7422d600e0b7dcf3a3.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/field.cc')
-rw-r--r-- | sql/field.cc | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/sql/field.cc b/sql/field.cc index 1e42a53e45a..fcd5ed6f84f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8455,9 +8455,12 @@ const char *Field_bit::unpack(char *to, const char *from) void Field_bit::set_default() { - my_ptrdiff_t const offset= table->s->default_values - table->record[0]; - uchar bits= get_rec_bits(bit_ptr + offset, bit_ofs, bit_len); - set_rec_bits(bits, bit_ptr, bit_ofs, bit_len); + if (bit_len > 0) + { + my_ptrdiff_t const offset= table->s->default_values - table->record[0]; + uchar bits= get_rec_bits(bit_ptr + offset, bit_ofs, bit_len); + set_rec_bits(bits, bit_ptr, bit_ofs, bit_len); + } Field::set_default(); } |