Commit bf9404d3 authored by Sergei Golubchik's avatar Sergei Golubchik

protect against corrupted frms

when reading table options
parent bba3d42a
...@@ -685,20 +685,25 @@ uchar *engine_table_options_frm_image(uchar *buff, ...@@ -685,20 +685,25 @@ uchar *engine_table_options_frm_image(uchar *buff,
@returns pointer to byte after last recorded in the buffer @returns pointer to byte after last recorded in the buffer
*/ */
uchar *engine_option_value::frm_read(const uchar *buff, engine_option_value **start, uchar *engine_option_value::frm_read(const uchar *buff, const uchar *buff_end,
engine_option_value **start,
engine_option_value **end, MEM_ROOT *root) engine_option_value **end, MEM_ROOT *root)
{ {
LEX_STRING name, value; LEX_STRING name, value;
uint len; uint len;
#define need_buff(N) if (buff + (N) >= buff_end) return NULL
need_buff(3);
name.length= buff[0]; name.length= buff[0];
buff++; buff++;
need_buff(name.length + 2);
if (!(name.str= strmake_root(root, (const char*)buff, name.length))) if (!(name.str= strmake_root(root, (const char*)buff, name.length)))
return NULL; return NULL;
buff+= name.length; buff+= name.length;
len= uint2korr(buff); len= uint2korr(buff);
value.length= len & ~FRM_QUOTED_VALUE; value.length= len & ~FRM_QUOTED_VALUE;
buff+= 2; buff+= 2;
need_buff(value.length);
if (!(value.str= strmake_root(root, (const char*)buff, value.length))) if (!(value.str= strmake_root(root, (const char*)buff, value.length)))
return NULL; return NULL;
buff+= value.length; buff+= value.length;
...@@ -735,8 +740,8 @@ bool engine_table_options_frm_read(const uchar *buff, uint length, ...@@ -735,8 +740,8 @@ bool engine_table_options_frm_read(const uchar *buff, uint length,
while (buff < buff_end && *buff) while (buff < buff_end && *buff)
{ {
if (!(buff= engine_option_value::frm_read(buff, &share->option_list, &end, if (!(buff= engine_option_value::frm_read(buff, buff_end,
root))) &share->option_list, &end, root)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
buff++; buff++;
...@@ -745,7 +750,7 @@ bool engine_table_options_frm_read(const uchar *buff, uint length, ...@@ -745,7 +750,7 @@ bool engine_table_options_frm_read(const uchar *buff, uint length,
{ {
while (buff < buff_end && *buff) while (buff < buff_end && *buff)
{ {
if (!(buff= engine_option_value::frm_read(buff, if (!(buff= engine_option_value::frm_read(buff, buff_end,
&share->field[count]->option_list, &share->field[count]->option_list,
&end, root))) &end, root)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
...@@ -757,7 +762,7 @@ bool engine_table_options_frm_read(const uchar *buff, uint length, ...@@ -757,7 +762,7 @@ bool engine_table_options_frm_read(const uchar *buff, uint length,
{ {
while (buff < buff_end && *buff) while (buff < buff_end && *buff)
{ {
if (!(buff= engine_option_value::frm_read(buff, if (!(buff= engine_option_value::frm_read(buff, buff_end,
&share->key_info[count].option_list, &share->key_info[count].option_list,
&end, root))) &end, root)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
......
...@@ -66,7 +66,8 @@ class engine_option_value: public Sql_alloc ...@@ -66,7 +66,8 @@ class engine_option_value: public Sql_alloc
link(start, end); link(start, end);
} }
} }
static uchar *frm_read(const uchar *buff, engine_option_value **start, static uchar *frm_read(const uchar *buff, const uchar *buff_end,
engine_option_value **start,
engine_option_value **end, MEM_ROOT *root); engine_option_value **end, MEM_ROOT *root);
void link(engine_option_value **start, engine_option_value **end); void link(engine_option_value **start, engine_option_value **end);
uint frm_length(); uint frm_length();
......
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