summaryrefslogtreecommitdiff
path: root/sql/create_options.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-05-04 16:05:30 +0200
committerSergei Golubchik <serg@mariadb.org>2016-05-05 01:05:05 +0200
commitbf9404d3a493ba122bc46c0fadf33d8cda9d0d3f (patch)
treef2b9467bf68d626f84c1050a1e2d54280f331444 /sql/create_options.cc
parentbba3d42a1f2566dd8ab11d5910444409c93b8194 (diff)
downloadmariadb-git-bf9404d3a493ba122bc46c0fadf33d8cda9d0d3f.tar.gz
protect against corrupted frms
when reading table options
Diffstat (limited to 'sql/create_options.cc')
-rw-r--r--sql/create_options.cc15
1 files changed, 10 insertions, 5 deletions
diff --git a/sql/create_options.cc b/sql/create_options.cc
index 66515be05b8..40e4e8b321c 100644
--- a/sql/create_options.cc
+++ b/sql/create_options.cc
@@ -685,20 +685,25 @@ uchar *engine_table_options_frm_image(uchar *buff,
@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)
{
LEX_STRING name, value;
uint len;
+#define need_buff(N) if (buff + (N) >= buff_end) return NULL
+ need_buff(3);
name.length= buff[0];
buff++;
+ need_buff(name.length + 2);
if (!(name.str= strmake_root(root, (const char*)buff, name.length)))
return NULL;
buff+= name.length;
len= uint2korr(buff);
value.length= len & ~FRM_QUOTED_VALUE;
buff+= 2;
+ need_buff(value.length);
if (!(value.str= strmake_root(root, (const char*)buff, value.length)))
return NULL;
buff+= value.length;
@@ -735,8 +740,8 @@ bool engine_table_options_frm_read(const uchar *buff, uint length,
while (buff < buff_end && *buff)
{
- if (!(buff= engine_option_value::frm_read(buff, &share->option_list, &end,
- root)))
+ if (!(buff= engine_option_value::frm_read(buff, buff_end,
+ &share->option_list, &end, root)))
DBUG_RETURN(TRUE);
}
buff++;
@@ -745,7 +750,7 @@ bool engine_table_options_frm_read(const uchar *buff, uint length,
{
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,
&end, root)))
DBUG_RETURN(TRUE);
@@ -757,7 +762,7 @@ bool engine_table_options_frm_read(const uchar *buff, uint length,
{
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,
&end, root)))
DBUG_RETURN(TRUE);