Commit c045d1dc authored by Satya B's avatar Satya B

Fix for Bug #43973 - backup_myisam.test fails on 6.0-bugteam

      
The test started failing following the push for BUG#41541.
Some of the algorithms access bytes beyond the input data
and this can affect up to one byte less than "word size"
which is BITS_SAVED / 8. 
      
Fixed by adding (BITS_SAVED / 8) -1 bytes to buffer size
(i.e. Memory Segment #2) to avoid accessing un-allocated data.
parent aebaf079
...@@ -208,10 +208,17 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys) ...@@ -208,10 +208,17 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
This segment will be reallocated after construction of the tables. This segment will be reallocated after construction of the tables.
*/ */
length=(uint) (elements*2+trees*(1 << myisam_quick_table_bits)); length=(uint) (elements*2+trees*(1 << myisam_quick_table_bits));
/*
To keep some algorithms simpler, we accept that they access
bytes beyond the end of the input data. This can affect up to
one byte less than the "word size" size used in this file,
which is BITS_SAVED / 8. To avoid accessing non-allocated
data, we add (BITS_SAVED / 8) - 1 bytes to the buffer size.
*/
if (!(share->decode_tables=(uint16*) if (!(share->decode_tables=(uint16*)
my_malloc((length + OFFSET_TABLE_SIZE) * sizeof(uint16) + my_malloc((length + OFFSET_TABLE_SIZE) * sizeof(uint16) +
(uint) (share->pack.header_length - sizeof(header)), (uint) (share->pack.header_length - sizeof(header) +
MYF(MY_WME | MY_ZEROFILL)))) (BITS_SAVED / 8) - 1), MYF(MY_WME | MY_ZEROFILL))))
goto err1; goto err1;
tmp_buff=share->decode_tables+length; tmp_buff=share->decode_tables+length;
disk_cache=(byte*) (tmp_buff+OFFSET_TABLE_SIZE); disk_cache=(byte*) (tmp_buff+OFFSET_TABLE_SIZE);
...@@ -1430,31 +1437,6 @@ static void fill_buffer(MI_BIT_BUFF *bit_buff) ...@@ -1430,31 +1437,6 @@ static void fill_buffer(MI_BIT_BUFF *bit_buff)
bit_buff->current_byte=0; bit_buff->current_byte=0;
return; return;
} }
else
{
uint len= 0;
uint i= 0;
/*
Check if the remaining buffer/record to read is less than the word size.
If so read byte by byte
Note: if this branch becomes a bottleneck it can be removed, assuming
that the second memory segment allocates 7 extra bytes (see
_mi_read_pack_info()).
*/
len= bit_buff->end - bit_buff->pos;
if (len < (BITS_SAVED / 8))
{
bit_buff->current_byte= 0;
for (i=0 ; i < len ; i++)
{
bit_buff->current_byte+= (((uint) ((uchar) bit_buff->pos[len - i - 1]))
<< (8 * i));
}
bit_buff->pos= bit_buff->end;
return;
}
}
#if BITS_SAVED == 64 #if BITS_SAVED == 64
bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) + bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) +
......
...@@ -38,3 +38,25 @@ SELECT COUNT(*) FROM t1; ...@@ -38,3 +38,25 @@ SELECT COUNT(*) FROM t1;
COUNT(*) COUNT(*)
1024 1024
DROP TABLE t1; DROP TABLE t1;
#
# Bug #43973 - backup_myisam.test fails on 6.0-bugteam
#
CREATE DATABASE mysql_db1;
CREATE TABLE mysql_db1.t1 (c1 VARCHAR(5), c2 int);
CREATE INDEX i1 ON mysql_db1.t1 (c1, c2);
INSERT INTO mysql_db1.t1 VALUES ('A',1);
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
FLUSH TABLE mysql_db1.t1;
# Compress the table using MYISAMPACK tool
# Run MYISAMCHK tool on the compressed table
SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;
COUNT(*)
128
DROP TABLE mysql_db1.t1;
DROP DATABASE mysql_db1;
...@@ -50,3 +50,28 @@ FLUSH TABLE t1; ...@@ -50,3 +50,28 @@ FLUSH TABLE t1;
--exec $MYISAMPACK $MYSQLTEST_VARDIR/master-data/test/t1 --exec $MYISAMPACK $MYSQLTEST_VARDIR/master-data/test/t1
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug #43973 - backup_myisam.test fails on 6.0-bugteam
--echo #
CREATE DATABASE mysql_db1;
CREATE TABLE mysql_db1.t1 (c1 VARCHAR(5), c2 int);
CREATE INDEX i1 ON mysql_db1.t1 (c1, c2);
INSERT INTO mysql_db1.t1 VALUES ('A',1);
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
FLUSH TABLE mysql_db1.t1;
#
--echo # Compress the table using MYISAMPACK tool
--exec $MYISAMPACK -s $MYSQLTEST_VARDIR/master-data/mysql_db1/t1
--echo # Run MYISAMCHK tool on the compressed table
--exec $MYISAMCHK -srq $MYSQLTEST_VARDIR/master-data/mysql_db1/t1
SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;
#
DROP TABLE mysql_db1.t1;
DROP DATABASE mysql_db1;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment