summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2018-05-26 17:03:00 +0300
committerMonty <monty@mariadb.org>2018-05-26 17:03:00 +0300
commit13c241c64f4609776169fd8a807270ad99241ca3 (patch)
treedb4bfe700a5196048567bd2cc87b6e7550b11511 /sql
parent2d62a4cb2fc116c084d366619808cc4419d9dced (diff)
downloadmariadb-git-13c241c64f4609776169fd8a807270ad99241ca3.tar.gz
Fixed memory overrun in binlog_encryption.encrypted_master
Problem was that max_row_lengt() used different bitmap than pack_row()
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_class.cc12
-rw-r--r--sql/table.cc6
-rw-r--r--sql/table.h2
3 files changed, 12 insertions, 8 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 577007dad38..7e15eff4dd4 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -6414,7 +6414,8 @@ int THD::binlog_write_row(TABLE* table, bool is_trans,
Pack records into format for transfer. We are allocating more
memory than needed, but that doesn't matter.
*/
- Row_data_memory memory(table, max_row_length(table, record));
+ Row_data_memory memory(table, max_row_length(table, table->rpl_write_set,
+ record));
if (!memory.has_memory())
return HA_ERR_OUT_OF_MEM;
@@ -6451,8 +6452,10 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
((WSREP(this) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()));
- size_t const before_maxlen = max_row_length(table, before_record);
- size_t const after_maxlen = max_row_length(table, after_record);
+ size_t const before_maxlen= max_row_length(table, table->read_set,
+ before_record);
+ size_t const after_maxlen= max_row_length(table, table->rpl_write_set,
+ after_record);
Row_data_memory row_data(table, before_maxlen, after_maxlen);
if (!row_data.has_memory())
@@ -6528,7 +6531,8 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans,
Pack records into format for transfer. We are allocating more
memory than needed, but that doesn't matter.
*/
- Row_data_memory memory(table, max_row_length(table, record));
+ Row_data_memory memory(table, max_row_length(table, table->read_set,
+ record));
if (unlikely(!memory.has_memory()))
return HA_ERR_OUT_OF_MEM;
diff --git a/sql/table.cc b/sql/table.cc
index b0e1f07a881..040eec0d2e8 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -7279,7 +7279,7 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl)
}
-size_t max_row_length(TABLE *table, const uchar *data)
+size_t max_row_length(TABLE *table, MY_BITMAP const *cols, const uchar *data)
{
TABLE_SHARE *table_s= table->s;
size_t length= table_s->reclength + 2 * table_s->fields;
@@ -7291,11 +7291,11 @@ size_t max_row_length(TABLE *table, const uchar *data)
for (uint *ptr= beg ; ptr != end ; ++ptr)
{
Field * const field= table->field[*ptr];
- if (bitmap_is_set(table->read_set, field->field_index) &&
+ if (bitmap_is_set(cols, field->field_index) &&
!field->is_null(rec_offset))
{
Field_blob * const blob= (Field_blob*) field;
- length+= blob->get_length(rec_offset) + HA_KEY_BLOB_LENGTH;
+ length+= blob->get_length(rec_offset) + 8; /* max blob store length */
}
}
DBUG_PRINT("exit", ("length: %lld", (longlong) length));
diff --git a/sql/table.h b/sql/table.h
index 61ac6c06e38..6febeb555f9 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -2672,7 +2672,7 @@ enum get_table_share_flags {
GTS_FORCE_DISCOVERY = 16
};
-size_t max_row_length(TABLE *table, const uchar *data);
+size_t max_row_length(TABLE *table, MY_BITMAP const *cols, const uchar *data);
void init_mdl_requests(TABLE_LIST *table_list);