#At file:///home/satya/WORK/mysql-5.1-bugteam-41541/ based on revid:mats@stripped
2754 Satya B 2009-02-25
Fix for BUG#41541 - Valgrind warnings on packed MyISAM table
myisampack tool with valgrind throws "invalid read size" errors
when a table with varchar or text field exist
This happens because when we try to read a record into the buffer
we alway assume that the remaing buffer to read is always equal
to word size(4 or 8 or 2 bytes) we read. Sometimes we have buffer
size less than word size and trying to read the entire word size
will end up in valgrind errors
Fixed by reading byte by byte when we detect the buffer size is
less than the word size
modified:
mysql-test/r/myisampack.result
mysql-test/t/myisampack.test
storage/myisam/mi_packrec.c
per-file messages:
mysql-test/r/myisampack.result
result file generated with varchar and extra fields
mysql-test/t/myisampack.test
modified the existing testcase by adding varchar and text fields
storage/myisam/mi_packrec.c
Fixed fill_buffer() to read byte by byte when the remaining
buffer size is less than word size
=== modified file 'mysql-test/r/myisampack.result'
--- a/mysql-test/r/myisampack.result 2009-01-22 05:55:26 +0000
+++ b/mysql-test/r/myisampack.result 2009-02-25 12:22:46 +0000
@@ -28,8 +28,8 @@ Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
drop table if exists t1;
-create table t1(f1 int, f2 char(255));
-insert into t1 values(1, 'foo'), (2, 'bar');
+create table t1(f1 int, f2 char(255), f3 varchar(200), f4 text);
+insert into t1 values(1, 'foo', 'foo1', 'foo2'), (2, 'bar', 'bar1', 'bar2');
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
=== modified file 'mysql-test/t/myisampack.test'
--- a/mysql-test/t/myisampack.test 2009-01-30 13:44:49 +0000
+++ b/mysql-test/t/myisampack.test 2009-02-25 12:22:46 +0000
@@ -37,12 +37,14 @@ DROP TABLE t1;
# Bug#40949 Debug version of MySQL server crashes when run OPTIMIZE on compressed table.
# expanded with testcase for
# BUG#41574 - REPAIR TABLE: crashes for compressed tables
+# modified with testcase for
+# BUG#41541 - Valgrind warnings on packed MyISAM table
#
--disable_warnings
drop table if exists t1;
--enable_warnings
-create table t1(f1 int, f2 char(255));
-insert into t1 values(1, 'foo'), (2, 'bar');
+create table t1(f1 int, f2 char(255), f3 varchar(200), f4 text);
+insert into t1 values(1, 'foo', 'foo1', 'foo2'), (2, 'bar', 'bar1', 'bar2');
insert into t1 select * from t1;
insert into t1 select * from t1;
insert into t1 select * from t1;
=== modified file 'storage/myisam/mi_packrec.c'
--- a/storage/myisam/mi_packrec.c 2008-03-31 07:40:39 +0000
+++ b/storage/myisam/mi_packrec.c 2009-02-25 12:22:46 +0000
@@ -1425,12 +1425,31 @@ static uint fill_and_get_bits(MI_BIT_BUF
static void fill_buffer(MI_BIT_BUFF *bit_buff)
{
+ uint no_rem_bytes=0, i=0;
if (bit_buff->pos >= bit_buff->end)
{
bit_buff->error= 1;
bit_buff->current_byte=0;
return;
}
+ else
+ {
+ /*
+ Check if the remaining buffer/record to read is less than the word size.
+ If so read byte by byte
+ */
+ no_rem_bytes= bit_buff->end - bit_buff->pos;
+ if (no_rem_bytes < (BITS_SAVED / 8))
+ {
+ for ( i=0 ; i < no_rem_bytes ; i++)
+ {
+ bit_buff->current_byte+= (((uint) ((uchar) bit_buff->pos[no_rem_bytes - i - 1 ])) << (8*i));
+ }
+ bit_buff->pos= bit_buff->end;
+ return;
+ }
+ }
+
#if BITS_SAVED == 64
bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) +
(((uint) ((uchar) bit_buff->pos[6])) << 8) +