summaryrefslogtreecommitdiff
path: root/sql/field.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
commit4924c61999cac4738f7f4a7422d600e0b7dcf3a3 (patch)
treec7b5012b7bab4c808f1bdbd7e09c51510c19585e /sql/field.cc
parent2138534c134c89eb68cf17a3c7534a3459c1ea5b (diff)
downloadmariadb-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.cc9
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();
}