Commit e2cf8b30 authored by ingo@mysql.com's avatar ingo@mysql.com

Bug#9487 - myisampack segmentation violation and bus error

Fixed some casts for 64-bit systems.
Fixed a possible buffer overflow.
parent a1f7f57b
...@@ -1709,7 +1709,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts) ...@@ -1709,7 +1709,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
ulong tot_blob_length=0; ulong tot_blob_length=0;
if (! error) if (! error)
{ {
if (flush_buffer(max_calc_length+max_pack_length)) if (flush_buffer((ulong) max_calc_length + (ulong) max_pack_length))
break; break;
record_pos=file_buffer.pos; record_pos=file_buffer.pos;
file_buffer.pos+=max_pack_length; file_buffer.pos+=max_pack_length;
...@@ -1930,7 +1930,20 @@ static void init_file_buffer(File file, pbool read_buffer) ...@@ -1930,7 +1930,20 @@ static void init_file_buffer(File file, pbool read_buffer)
static int flush_buffer(ulong neaded_length) static int flush_buffer(ulong neaded_length)
{ {
ulong length; ulong length;
if ((ulong) (file_buffer.end - file_buffer.pos) > neaded_length)
/*
file_buffer.end is 8 bytes lower than the real end of the buffer.
This is done so that the end-of-buffer condition does not need to be
checked for every byte (see write_bits()). Consequently,
file_buffer.pos can become greater than file_buffer.end. The
algorithms in the other functions ensure that there will never be
more than 8 bytes written to the buffer without an end-of-buffer
check. So the buffer cannot be overrun. But we need to check for the
near-to-buffer-end condition to avoid a negative result, which is
casted to unsigned and thus becomes giant.
*/
if ((file_buffer.pos < file_buffer.end) &&
((ulong) (file_buffer.end - file_buffer.pos) > neaded_length))
return 0; return 0;
length=(ulong) (file_buffer.pos-file_buffer.buffer); length=(ulong) (file_buffer.pos-file_buffer.buffer);
file_buffer.pos=file_buffer.buffer; file_buffer.pos=file_buffer.buffer;
...@@ -2002,7 +2015,7 @@ static void write_bits (register ulong value, register uint bits) ...@@ -2002,7 +2015,7 @@ static void write_bits (register ulong value, register uint bits)
} }
#endif #endif
if (file_buffer.pos >= file_buffer.end) if (file_buffer.pos >= file_buffer.end)
VOID(flush_buffer((uint) ~0)); VOID(flush_buffer(~ (ulong) 0));
file_buffer.bits=(int) (BITS_SAVED - bits); file_buffer.bits=(int) (BITS_SAVED - bits);
file_buffer.current_byte=(uint) (value << (BITS_SAVED - bits)); file_buffer.current_byte=(uint) (value << (BITS_SAVED - bits));
} }
......
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