summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
authormonty@mysql.com <>2004-12-06 11:38:56 +0200
committermonty@mysql.com <>2004-12-06 11:38:56 +0200
commit0de4777187a869b4a070ba1e0da28a2ffe1abf05 (patch)
treea7bb331b7dac7ac2b3cda915e99bb8c1333f4fec /myisam
parent86508ad9690c61e806acf308b57c6431b1a2dd99 (diff)
parentdededf09fa8cb1096549e74f543c84b81e413066 (diff)
downloadmariadb-git-0de4777187a869b4a070ba1e0da28a2ffe1abf05.tar.gz
Merge with 4.1
Diffstat (limited to 'myisam')
-rw-r--r--myisam/mi_packrec.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c
index 94eb2de17e2..a277c2ca9d1 100644
--- a/myisam/mi_packrec.c
+++ b/myisam/mi_packrec.c
@@ -42,8 +42,9 @@
{ bits-=(bit+1); break; } \
pos+= *pos
+#define OFFSET_TABLE_SIZE 512
-static void read_huff_table(MI_BIT_BUFF *bit_buff,MI_DECODE_TREE *decode_tree,
+static uint read_huff_table(MI_BIT_BUFF *bit_buff,MI_DECODE_TREE *decode_tree,
uint16 **decode_table,byte **intervall_buff,
uint16 *tmp_buff);
static void make_quick_table(uint16 *to_table,uint16 *decode_table,
@@ -53,7 +54,7 @@ static void fill_quick_table(uint16 *table,uint bits, uint max_bits,
uint value);
static uint copy_decode_table(uint16 *to_pos,uint offset,
uint16 *decode_table);
-static uint find_longest_bitstream(uint16 *table);
+static uint find_longest_bitstream(uint16 *table, uint16 *end);
static void (*get_unpack_function(MI_COLUMNDEF *rec))(MI_COLUMNDEF *field,
MI_BIT_BUFF *buff,
uchar *to,
@@ -146,12 +147,12 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
{
if (!my_errno)
my_errno=HA_ERR_END_OF_FILE;
- DBUG_RETURN(1);
+ goto err0;
}
if (memcmp((byte*) header,(byte*) myisam_pack_file_magic,4))
{
my_errno=HA_ERR_WRONG_IN_RECORD;
- DBUG_RETURN(1);
+ goto err0;
}
share->pack.header_length= uint4korr(header+4);
share->min_pack_length=(uint) uint4korr(header+8);
@@ -173,20 +174,20 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
my_malloc((uint) (trees*sizeof(MI_DECODE_TREE)+
intervall_length*sizeof(byte)),
MYF(MY_WME))))
- DBUG_RETURN(1);
+ goto err0;
intervall_buff=(byte*) (share->decode_trees+trees);
length=(uint) (elements*2+trees*(1 << myisam_quick_table_bits));
if (!(share->decode_tables=(uint16*)
- my_malloc((length+512)*sizeof(uint16)+
+ my_malloc((length+OFFSET_TABLE_SIZE)*sizeof(uint16)+
(uint) (share->pack.header_length+7),
MYF(MY_WME | MY_ZEROFILL))))
{
my_free((gptr) share->decode_trees,MYF(0));
- DBUG_RETURN(1);
+ goto err1;
}
tmp_buff=share->decode_tables+length;
- disk_cache=(byte*) (tmp_buff+512);
+ disk_cache=(byte*) (tmp_buff+OFFSET_TABLE_SIZE);
if (my_read(file,disk_cache,
(uint) (share->pack.header_length-sizeof(header)),
@@ -194,7 +195,7 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
{
my_free((gptr) share->decode_trees,MYF(0));
my_free((gptr) share->decode_tables,MYF(0));
- DBUG_RETURN(1);
+ goto err2;
}
huff_tree_bits=max_bit(trees ? trees-1 : 0);
@@ -213,8 +214,9 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
skip_to_next_byte(&bit_buff);
decode_table=share->decode_tables;
for (i=0 ; i < trees ; i++)
- read_huff_table(&bit_buff,share->decode_trees+i,&decode_table,
- &intervall_buff,tmp_buff);
+ if (read_huff_table(&bit_buff,share->decode_trees+i,&decode_table,
+ &intervall_buff,tmp_buff))
+ goto err3;
decode_table=(uint16*)
my_realloc((gptr) share->decode_tables,
(uint) ((byte*) decode_table - (byte*) share->decode_tables),
@@ -224,8 +226,7 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
share->decode_tables=decode_table;
for (i=0 ; i < trees ; i++)
share->decode_trees[i].table=ADD_TO_PTR(share->decode_trees[i].table,
- diff,
- uint16*);
+ diff, uint16*);
}
/* Fix record-ref-length for keys */
@@ -242,19 +243,24 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
}
if (bit_buff.error || bit_buff.pos < bit_buff.end)
- { /* info_length was wrong */
- my_errno=HA_ERR_WRONG_IN_RECORD;
- my_free((gptr) share->decode_trees,MYF(0));
- my_free((gptr) share->decode_tables,MYF(0));
- DBUG_RETURN(1);
- }
+ goto err3;
+
DBUG_RETURN(0);
+
+err3:
+ my_errno=HA_ERR_WRONG_IN_RECORD;
+err2:
+ my_free((gptr) share->decode_tables,MYF(0));
+err1:
+ my_free((gptr) share->decode_trees,MYF(0));
+err0:
+ DBUG_RETURN(1);
}
/* Read on huff-code-table from datafile */
-static void read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree,
+static uint read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree,
uint16 **decode_table, byte **intervall_buff,
uint16 *tmp_buff)
{
@@ -297,7 +303,9 @@ static void read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree,
decode_tree->intervalls= *intervall_buff;
if (! intervall_length)
{
- table_bits=find_longest_bitstream(tmp_buff);
+ table_bits=find_longest_bitstream(tmp_buff, tmp_buff+OFFSET_TABLE_SIZE);
+ if (table_bits == (uint) ~0)
+ return 1;
if (table_bits > myisam_quick_table_bits)
table_bits=myisam_quick_table_bits;
next_free_offset= (1 << table_bits);
@@ -315,7 +323,7 @@ static void read_huff_table(MI_BIT_BUFF *bit_buff, MI_DECODE_TREE *decode_tree,
bit_buff->pos+=intervall_length;
bit_buff->bits=0;
}
- return;
+ return 0;
}
@@ -390,15 +398,23 @@ static uint copy_decode_table(uint16 *to_pos, uint offset,
}
-static uint find_longest_bitstream(uint16 *table)
+static uint find_longest_bitstream(uint16 *table, uint16 *end)
{
uint length=1,length2;
if (!(*table & IS_CHAR))
- length=find_longest_bitstream(table+ *table)+1;
+ {
+ uint16 *next= table + *table;
+ if (next > end || next == table)
+ return ~0;
+ length=find_longest_bitstream(next, end)+1;
+ }
table++;
if (!(*table & IS_CHAR))
{
- length2=find_longest_bitstream(table+ *table)+1;
+ uint16 *next= table + *table;
+ if (next > end || next == table)
+ return ~0;
+ length2=find_longest_bitstream(table+ *table, end)+1;
length=max(length,length2);
}
return length;