summaryrefslogtreecommitdiff
path: root/sql/log_event.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r--sql/log_event.cc90
1 files changed, 68 insertions, 22 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index b29dd401741..5496b7ec97e 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1,5 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,7 +35,7 @@
#include "rpl_utility.h"
#include "rpl_record.h"
#include <my_dir.h>
-#include "sql_show.h"
+#include "sql_show.h" // append_identifier
#endif /* MYSQL_CLIENT */
@@ -54,6 +55,22 @@
*/
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
+/*
+ Explicit instantiation to unsigned int of template available_buffer
+ function.
+*/
+template unsigned int available_buffer<unsigned int>(const char*,
+ const char*,
+ unsigned int);
+
+/*
+ Explicit instantiation to unsigned int of template valid_buffer_range
+ function.
+*/
+template bool valid_buffer_range<unsigned int>(unsigned int,
+ const char*,
+ const char*,
+ unsigned int);
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
@@ -1285,7 +1302,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
ev = new Rand_log_event(buf, description_event);
break;
case USER_VAR_EVENT:
- ev = new User_var_log_event(buf, description_event);
+ ev = new User_var_log_event(buf, event_len, description_event);
break;
case FORMAT_DESCRIPTION_EVENT:
ev = new Format_description_log_event(buf, event_len, description_event);
@@ -1695,11 +1712,11 @@ beg:
int i, end;
char buff[512], *pos;
pos= buff;
- pos+= my_sprintf(buff, (buff, "%s", dec.sign() ? "-" : ""));
+ pos+= sprintf(buff, "%s", dec.sign() ? "-" : "");
end= ROUND_UP(dec.frac) + ROUND_UP(dec.intg)-1;
for (i=0; i < end; i++)
- pos+= my_sprintf(pos, (pos, "%09d.", dec.buf[i]));
- pos+= my_sprintf(pos, (pos, "%09d", dec.buf[i]));
+ pos+= sprintf(pos, "%09d.", dec.buf[i]);
+ pos+= sprintf(pos, "%09d", dec.buf[i]);
my_b_printf(file, "%s", buff);
my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
precision, decimals);
@@ -1982,7 +1999,7 @@ void Rows_log_event::print_verbose(IO_CACHE *file,
for (const uchar *value= m_rows_buf; value < m_rows_end; )
{
size_t length;
- my_b_printf(file, "### %s %s.%s\n",
+ my_b_printf(file, "### %s %`s.%`s\n",
sql_command,
map->get_db_name(), map->get_table_name());
/* Print the first image */
@@ -2151,7 +2168,7 @@ void Query_log_event::pack_info(THD *thd, Protocol *protocol)
{
buf.append(STRING_WITH_LEN("use "));
append_identifier(thd, &buf, db, db_len);
- buf.append("; ");
+ buf.append(STRING_WITH_LEN("; "));
}
if (query && q_len)
buf.append(query, q_len);
@@ -2945,17 +2962,11 @@ void Query_log_event::print_query_header(IO_CACHE* file,
}
else if (db)
{
- /* Room for expand ` to `` + initial/final ` + \0 */
- char buf[FN_REFLEN*2+3];
-
different_db= memcmp(print_event_info->db, db, db_len + 1);
if (different_db)
memcpy(print_event_info->db, db, db_len + 1);
if (db[0] && different_db)
- {
- my_snprintf(buf, sizeof(buf), "%`s", db);
- my_b_printf(file, "use %s%s\n", buf, print_event_info->delimiter);
- }
+ my_b_printf(file, "use %`s%s\n", db, print_event_info->delimiter);
}
end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
@@ -4583,7 +4594,7 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
}
if (db && db[0] && different_db)
- my_b_printf(&cache, "%suse %s%s\n",
+ my_b_printf(&cache, "%suse %`s%s\n",
commented ? "# " : "",
db, print_event_info->delimiter);
@@ -4635,7 +4646,7 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
{
if (i)
my_b_printf(&cache, ",");
- my_b_printf(&cache, "%s", field);
+ my_b_printf(&cache, "%`s", field);
field += field_lens[i] + 1;
}
@@ -5672,18 +5683,34 @@ void User_var_log_event::pack_info(THD *thd, Protocol* protocol)
User_var_log_event::
-User_var_log_event(const char* buf,
+User_var_log_event(const char* buf, uint event_len,
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
#ifndef MYSQL_CLIENT
, deferred(false)
#endif
{
+ bool error= false;
+ const char* buf_start= buf;
/* The Post-Header is empty. The Variable Data part begins immediately. */
buf+= description_event->common_header_len +
description_event->post_header_len[USER_VAR_EVENT-1];
name_len= uint4korr(buf);
name= (char *) buf + UV_NAME_LEN_SIZE;
+
+ /*
+ We don't know yet is_null value, so we must assume that name_len
+ may have the bigger value possible, is_null= True and there is no
+ payload for val.
+ */
+ if (0 == name_len ||
+ !valid_buffer_range<uint>(name_len, buf_start, name,
+ event_len - UV_VAL_IS_NULL))
+ {
+ error= true;
+ goto err;
+ }
+
buf+= UV_NAME_LEN_SIZE + name_len;
is_null= (bool) *buf;
if (is_null)
@@ -5695,13 +5722,31 @@ User_var_log_event(const char* buf,
}
else
{
+ if (!valid_buffer_range<uint>(UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE
+ + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE,
+ buf_start, buf, event_len))
+ {
+ error= true;
+ goto err;
+ }
+
type= (Item_result) buf[UV_VAL_IS_NULL];
charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
UV_CHARSET_NUMBER_SIZE);
val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
+
+ if (!valid_buffer_range<uint>(val_len, buf_start, val, event_len))
+ {
+ error= true;
+ goto err;
+ }
}
+
+err:
+ if (error)
+ name= 0;
}
@@ -5843,8 +5888,9 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
char *hex_str;
CHARSET_INFO *cs;
- if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
- break; // no error, as we are 'void'
+ hex_str= (char *)my_malloc(2*val_len+1+2,MYF(MY_WME)); // 2 hex digits / byte
+ if (!hex_str)
+ return;
str_to_hex(hex_str, val, val_len);
/*
For proper behaviour when mysqlbinlog|mysql, we need to explicitely
@@ -5862,7 +5908,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
my_b_printf(&cache, ":=_%s %s COLLATE %`s%s\n",
cs->csname, hex_str, cs->name,
print_event_info->delimiter);
- my_afree(hex_str);
+ my_free(hex_str, MYF(MY_WME));
}
break;
case ROW_RESULT:
@@ -7085,9 +7131,9 @@ void Execute_load_query_log_event::pack_info(THD *thd, Protocol *protocol)
buf.real_alloc(9 + db_len + q_len + 10 + 21);
if (db && db_len)
{
- if (buf.append("use ") ||
+ if (buf.append(STRING_WITH_LEN("use ")) ||
append_identifier(thd, &buf, db, db_len) ||
- buf.append("; "))
+ buf.append(STRING_WITH_LEN("; ")))
return;
}
if (query && q_len && buf.append(query, q_len))