|
|
@ -1,6 +1,6 @@ |
|
|
|
/*
|
|
|
|
Copyright (c) 2000, 2016, Oracle and/or its affiliates. |
|
|
|
Copyright (c) 2009, 2016, MariaDB |
|
|
|
Copyright (c) 2000, 2018, Oracle and/or its affiliates. |
|
|
|
Copyright (c) 2009, 2018, MariaDB |
|
|
|
|
|
|
|
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 |
|
|
@ -3333,6 +3333,25 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, |
|
|
|
db= (char *)start; |
|
|
|
query= (char *)(start + db_len + 1); |
|
|
|
q_len= data_len - db_len -1; |
|
|
|
|
|
|
|
if (data_len && (data_len < db_len || |
|
|
|
data_len < q_len || |
|
|
|
data_len != (db_len + q_len + 1))) |
|
|
|
{ |
|
|
|
q_len= 0; |
|
|
|
query= NULL; |
|
|
|
DBUG_VOID_RETURN; |
|
|
|
} |
|
|
|
|
|
|
|
unsigned int max_length; |
|
|
|
max_length= (event_len - ((const char*)(end + db_len + 1) - |
|
|
|
(buf - common_header_len))); |
|
|
|
if (q_len != max_length) |
|
|
|
{ |
|
|
|
q_len= 0; |
|
|
|
query= NULL; |
|
|
|
DBUG_VOID_RETURN; |
|
|
|
} |
|
|
|
/**
|
|
|
|
Append the db length at the end of the buffer. This will be used by |
|
|
|
Query_cache::send_result_to_client() in case the query cache is On. |
|
|
@ -3613,6 +3632,20 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, |
|
|
|
you. |
|
|
|
*/ |
|
|
|
thd->catalog= catalog_len ? (char *) catalog : (char *)""; |
|
|
|
|
|
|
|
int len_error; |
|
|
|
size_t valid_len= system_charset_info->cset->well_formed_len(system_charset_info, |
|
|
|
db, db + db_len, db_len, &len_error); |
|
|
|
|
|
|
|
if (valid_len != db_len) |
|
|
|
{ |
|
|
|
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, |
|
|
|
ER_THD(thd, ER_SLAVE_FATAL_ERROR), |
|
|
|
"Invalid database name in Query event."); |
|
|
|
thd->is_slave_error= true; |
|
|
|
goto end; |
|
|
|
} |
|
|
|
|
|
|
|
new_db.length= db_len; |
|
|
|
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length); |
|
|
|
thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */ |
|
|
@ -3789,7 +3822,23 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, |
|
|
|
} |
|
|
|
else |
|
|
|
thd->variables.collation_database= thd->db_charset; |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
const CHARSET_INFO *cs= thd->charset(); |
|
|
|
/*
|
|
|
|
We cannot ask for parsing a statement using a character set |
|
|
|
without state_maps (parser internal data). |
|
|
|
*/ |
|
|
|
if (!cs->state_map) |
|
|
|
{ |
|
|
|
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, |
|
|
|
ER_THD(thd, ER_SLAVE_FATAL_ERROR), |
|
|
|
"character_set cannot be parsed"); |
|
|
|
thd->is_slave_error= true; |
|
|
|
goto end; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
thd->table_map_for_update= (table_map)table_map_for_update; |
|
|
|
thd->set_invoker(&user, &host); |
|
|
|
/*
|
|
|
@ -4256,7 +4305,13 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli) |
|
|
|
*/ |
|
|
|
break; |
|
|
|
default: |
|
|
|
/* this case is impossible */ |
|
|
|
/*
|
|
|
|
This case is not expected. It can be either an event corruption or an |
|
|
|
unsupported binary log version. |
|
|
|
*/ |
|
|
|
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, |
|
|
|
ER_THD(thd, ER_SLAVE_FATAL_ERROR), |
|
|
|
"Binlog version not supported"); |
|
|
|
DBUG_RETURN(1); |
|
|
|
} |
|
|
|
DBUG_RETURN(error); |
|
|
@ -5182,6 +5237,9 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, |
|
|
|
|
|
|
|
fields = (char*)field_lens + num_fields; |
|
|
|
table_name = fields + field_block_len; |
|
|
|
if (strlen(table_name) > NAME_LEN) |
|
|
|
goto err; |
|
|
|
|
|
|
|
db = table_name + table_name_len + 1; |
|
|
|
DBUG_EXECUTE_IF ("simulate_invalid_address", |
|
|
|
db_len = data_len;); |
|
|
@ -6378,6 +6436,13 @@ User_var_log_event(const char* buf, uint event_len, |
|
|
|
buf+= description_event->common_header_len + |
|
|
|
description_event->post_header_len[USER_VAR_EVENT-1]; |
|
|
|
name_len= uint4korr(buf); |
|
|
|
/* Avoid reading out of buffer */ |
|
|
|
if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len) |
|
|
|
{ |
|
|
|
error= true; |
|
|
|
goto err; |
|
|
|
} |
|
|
|
|
|
|
|
name= (char *) buf + UV_NAME_LEN_SIZE; |
|
|
|
|
|
|
|
/*
|
|
|
@ -6437,6 +6502,11 @@ User_var_log_event(const char* buf, uint event_len, |
|
|
|
we keep the flags set to UNDEF_F. |
|
|
|
*/ |
|
|
|
uint bytes_read= ((val + val_len) - start); |
|
|
|
if (bytes_read > event_len) |
|
|
|
{ |
|
|
|
error= true; |
|
|
|
goto err; |
|
|
|
} |
|
|
|
if ((data_written - bytes_read) > 0) |
|
|
|
{ |
|
|
|
flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + |
|
|
@ -6651,7 +6721,12 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) |
|
|
|
} |
|
|
|
|
|
|
|
if (!(charset= get_charset(charset_number, MYF(MY_WME)))) |
|
|
|
{ |
|
|
|
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, |
|
|
|
ER_THD(thd, ER_SLAVE_FATAL_ERROR), |
|
|
|
"Invalid character set for User var event"); |
|
|
|
DBUG_RETURN(1); |
|
|
|
} |
|
|
|
LEX_STRING user_var_name; |
|
|
|
user_var_name.str= name; |
|
|
|
user_var_name.length= name_len; |
|
|
@ -6672,12 +6747,26 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) |
|
|
|
{ |
|
|
|
switch (type) { |
|
|
|
case REAL_RESULT: |
|
|
|
if (val_len != 8) |
|
|
|
{ |
|
|
|
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, |
|
|
|
ER_THD(thd, ER_SLAVE_FATAL_ERROR), |
|
|
|
"Invalid variable length at User var event"); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
float8get(real_val, val); |
|
|
|
it= new Item_float(real_val, 0); |
|
|
|
val= (char*) &real_val; // Pointer to value in native format
|
|
|
|
val_len= 8; |
|
|
|
break; |
|
|
|
case INT_RESULT: |
|
|
|
if (val_len != 8) |
|
|
|
{ |
|
|
|
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, |
|
|
|
ER_THD(thd, ER_SLAVE_FATAL_ERROR), |
|
|
|
"Invalid variable length at User var event"); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
int_val= (longlong) uint8korr(val); |
|
|
|
it= new Item_int(int_val); |
|
|
|
val= (char*) &int_val; // Pointer to value in native format
|
|
|
@ -6685,6 +6774,13 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) |
|
|
|
break; |
|
|
|
case DECIMAL_RESULT: |
|
|
|
{ |
|
|
|
if (val_len < 3) |
|
|
|
{ |
|
|
|
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, |
|
|
|
ER_THD(thd, ER_SLAVE_FATAL_ERROR), |
|
|
|
"Invalid variable length at User var event"); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]); |
|
|
|
it= dec; |
|
|
|
val= (char *)dec->val_decimal(NULL); |
|
|
@ -8124,6 +8220,15 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, |
|
|
|
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); |
|
|
|
m_width = net_field_length(&ptr_after_width); |
|
|
|
DBUG_PRINT("debug", ("m_width=%lu", m_width)); |
|
|
|
/* Avoid reading out of buffer */ |
|
|
|
if (static_cast<unsigned int>((ptr_after_width + |
|
|
|
(m_width + 7) / 8) - |
|
|
|
(uchar*)buf) > event_len) |
|
|
|
{ |
|
|
|
m_cols.bitmap= NULL; |
|
|
|
DBUG_VOID_RETURN; |
|
|
|
} |
|
|
|
|
|
|
|
/* if bitmap_init fails, catched in is_valid() */ |
|
|
|
if (likely(!bitmap_init(&m_cols, |
|
|
|
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, |
|
|
@ -8172,7 +8277,12 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, |
|
|
|
|
|
|
|
const uchar* const ptr_rows_data= (const uchar*) ptr_after_width; |
|
|
|
|
|
|
|
size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf); |
|
|
|
size_t const read_size= ptr_rows_data - (const unsigned char *) buf; |
|
|
|
if (read_size > event_len) |
|
|
|
{ |
|
|
|
DBUG_VOID_RETURN; |
|
|
|
} |
|
|
|
size_t const data_size= event_len - read_size; |
|
|
|
DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu", |
|
|
|
m_table_id, m_flags, m_width, (ulong) data_size)); |
|
|
|
|
|
|
|