mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
protect against corrupted frms
when reading table options
This commit is contained in:
@ -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,
|
|||||||
|
|
||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
{
|
{
|
||||||
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
|
|||||||
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();
|
||||||
|
Reference in New Issue
Block a user