mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Merge 10.2 into 10.3
This commit is contained in:
119
sql/log_event.cc
119
sql/log_event.cc
@@ -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
|
||||
@@ -4831,6 +4831,24 @@ 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;
|
||||
}
|
||||
|
||||
uint32 max_length= uint32(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.
|
||||
@@ -5377,6 +5395,19 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
|
||||
you.
|
||||
*/
|
||||
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
|
||||
|
||||
size_t valid_len= Well_formed_prefix(system_charset_info,
|
||||
db, db_len, NAME_LEN).length();
|
||||
|
||||
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); /* allocates a copy of 'db' */
|
||||
@@ -5518,7 +5549,23 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Record any GTID in the same transaction, so slave state is
|
||||
transactionally consistent.
|
||||
@@ -6074,7 +6121,13 @@ int Start_log_event_v3::do_apply_event(rpl_group_info *rgi)
|
||||
*/
|
||||
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);
|
||||
@@ -6993,6 +7046,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;);
|
||||
@@ -9066,6 +9122,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;
|
||||
|
||||
/*
|
||||
@@ -9122,7 +9185,12 @@ User_var_log_event(const char* buf, uint event_len,
|
||||
Old events will not have this extra byte, thence,
|
||||
we keep the flags set to UNDEF_F.
|
||||
*/
|
||||
size_t bytes_read= ((val + val_len) - buf_start);
|
||||
size_t bytes_read= (val + val_len) - buf_start;
|
||||
if (bytes_read > size_t(event_len))
|
||||
{
|
||||
error= true;
|
||||
goto err;
|
||||
}
|
||||
if ((data_written - bytes_read) > 0)
|
||||
{
|
||||
flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
|
||||
@@ -9354,7 +9422,12 @@ int User_var_log_event::do_apply_event(rpl_group_info *rgi)
|
||||
}
|
||||
|
||||
if (!(charset= get_charset(charset_number, MYF(MY_WME))))
|
||||
{
|
||||
rgi->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_CSTRING user_var_name;
|
||||
user_var_name.str= name;
|
||||
user_var_name.length= name_len;
|
||||
@@ -9369,12 +9442,26 @@ int User_var_log_event::do_apply_event(rpl_group_info *rgi)
|
||||
{
|
||||
switch (type) {
|
||||
case REAL_RESULT:
|
||||
if (val_len != 8)
|
||||
{
|
||||
rgi->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 (thd->mem_root) Item_float(thd, real_val, 0);
|
||||
val= (char*) &real_val; // Pointer to value in native format
|
||||
val_len= 8;
|
||||
break;
|
||||
case INT_RESULT:
|
||||
if (val_len != 8)
|
||||
{
|
||||
rgi->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 (thd->mem_root) Item_int(thd, int_val);
|
||||
val= (char*) &int_val; // Pointer to value in native format
|
||||
@@ -9382,6 +9469,13 @@ int User_var_log_event::do_apply_event(rpl_group_info *rgi)
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
if (val_len < 3)
|
||||
{
|
||||
rgi->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 (thd->mem_root) Item_decimal(thd, (uchar*) val+2, val[0], val[1]);
|
||||
it= dec;
|
||||
val= (char *)dec->val_decimal(NULL);
|
||||
@@ -10797,6 +10891,14 @@ 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 (ptr_after_width + (m_width + 7) / 8 > (uchar*)buf + event_len)
|
||||
{
|
||||
m_cols.bitmap= NULL;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* if my_bitmap_init fails, catched in is_valid() */
|
||||
if (likely(!my_bitmap_init(&m_cols,
|
||||
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
|
||||
@@ -10845,7 +10947,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));
|
||||
|
||||
|
Reference in New Issue
Block a user