mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
MDEV-20917 InnoDB is passing NULL to nonnull function parameters
mem_heap_dup(): Avoid mem_heap_alloc() and memcpy() of data=NULL, len=0.
trx_undo_report_insert_virtual(), trx_undo_page_report_insert(),
trx_undo_page_report_modify(): Avoid memcpy(ptr, NULL, 0).
dfield_data_is_binary_equal(): Correctly handle data=NULL, len=0.
This clean-up was motivated by WITH_UBSAN, and no bug related to this
was observed in the wild. It should be noted that undefined behaviour
such as memcpy(ptr, NULL, 0) could allow compilers to perform unsafe
optimizations, like it was the case in
commit fc168c3a5e
(MDEV-15587).
This commit is contained in:
parent
2d82ae5ba3
commit
814534745b
5 changed files with 42 additions and 45 deletions
|
@ -168,7 +168,7 @@ dfield_data_is_binary_equal(
|
|||
const dfield_t* field, /*!< in: field */
|
||||
ulint len, /*!< in: data length or UNIV_SQL_NULL */
|
||||
const byte* data) /*!< in: data */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
MY_ATTRIBUTE((nonnull(1), warn_unused_result));
|
||||
|
||||
/*********************************************************************//**
|
||||
Gets info bits in a data tuple.
|
||||
|
|
|
@ -223,7 +223,7 @@ dfield_data_is_binary_equal(
|
|||
const byte* data) /*!< in: data */
|
||||
{
|
||||
return(len == dfield_get_len(field)
|
||||
&& (len == UNIV_SQL_NULL
|
||||
&& (!len || len == UNIV_SQL_NULL
|
||||
|| !memcmp(dfield_get_data(field), data, len)));
|
||||
}
|
||||
|
||||
|
|
|
@ -228,7 +228,22 @@ mem_strdupl(
|
|||
const char* str, /*!< in: string to be copied */
|
||||
ulint len); /*!< in: length of str, in bytes */
|
||||
|
||||
/** Duplicates a NUL-terminated string, allocated from a memory heap.
|
||||
/** Duplicate a block of data, allocated from a memory heap.
|
||||
@param[in] heap memory heap where string is allocated
|
||||
@param[in] data block of data to be copied
|
||||
@param[in] len length of data, in bytes
|
||||
@return own: a copy of data */
|
||||
inline
|
||||
void*
|
||||
mem_heap_dup(mem_heap_t* heap, const void* data, size_t len)
|
||||
{
|
||||
ut_ad(data || !len);
|
||||
return UNIV_LIKELY(data != NULL)
|
||||
? memcpy(mem_heap_alloc(heap, len), data, len)
|
||||
: NULL;
|
||||
}
|
||||
|
||||
/** Duplicate a NUL-terminated string, allocated from a memory heap.
|
||||
@param[in] heap memory heap where string is allocated
|
||||
@param[in] str string to be copied
|
||||
@return own: a copy of the string */
|
||||
|
@ -259,16 +274,6 @@ mem_heap_strcat(
|
|||
const char* s1, /*!< in: string 1 */
|
||||
const char* s2); /*!< in: string 2 */
|
||||
|
||||
/**********************************************************************//**
|
||||
Duplicate a block of data, allocated from a memory heap.
|
||||
@return own: a copy of the data */
|
||||
void*
|
||||
mem_heap_dup(
|
||||
/*=========*/
|
||||
mem_heap_t* heap, /*!< in: memory heap where copy is allocated */
|
||||
const void* data, /*!< in: data to be copied */
|
||||
ulint len); /*!< in: length of data, in bytes */
|
||||
|
||||
/****************************************************************//**
|
||||
A simple sprintf replacement that dynamically allocates the space for the
|
||||
formatted string from the given heap. This supports a very limited set of
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2019, MariaDB Corporation.
|
||||
|
||||
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 the Free Software
|
||||
|
@ -41,19 +41,6 @@ mem_heap_strdup(
|
|||
return(static_cast<char*>(mem_heap_dup(heap, str, strlen(str) + 1)));
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Duplicate a block of data, allocated from a memory heap.
|
||||
@return own: a copy of the data */
|
||||
void*
|
||||
mem_heap_dup(
|
||||
/*=========*/
|
||||
mem_heap_t* heap, /*!< in: memory heap where copy is allocated */
|
||||
const void* data, /*!< in: data to be copied */
|
||||
ulint len) /*!< in: length of data, in bytes */
|
||||
{
|
||||
return(memcpy(mem_heap_alloc(heap, len), data, len));
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Concatenate two strings and return the result, using a memory heap.
|
||||
@return own: the result */
|
||||
|
|
|
@ -412,9 +412,15 @@ trx_undo_report_insert_virtual(
|
|||
|
||||
const dfield_t* vfield = dtuple_get_nth_v_field(
|
||||
row, col->v_pos);
|
||||
ulint flen = vfield->len;
|
||||
switch (ulint flen = vfield->len) {
|
||||
case 0: case UNIV_SQL_NULL:
|
||||
if (trx_undo_left(undo_page, *ptr) < 5) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (flen != UNIV_SQL_NULL) {
|
||||
*ptr += mach_write_compressed(*ptr, flen);
|
||||
break;
|
||||
default:
|
||||
ulint max_len
|
||||
= dict_max_v_field_len_store_undo(
|
||||
table, col_no);
|
||||
|
@ -429,15 +435,8 @@ trx_undo_report_insert_virtual(
|
|||
}
|
||||
*ptr += mach_write_compressed(*ptr, flen);
|
||||
|
||||
ut_memcpy(*ptr, vfield->data, flen);
|
||||
memcpy(*ptr, vfield->data, flen);
|
||||
*ptr += flen;
|
||||
} else {
|
||||
if (trx_undo_left(undo_page, *ptr) < 5) {
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
*ptr += mach_write_compressed(*ptr, flen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -506,13 +505,16 @@ trx_undo_page_report_insert(
|
|||
|
||||
ptr += mach_write_compressed(ptr, flen);
|
||||
|
||||
if (flen != UNIV_SQL_NULL) {
|
||||
switch (flen) {
|
||||
case 0: case UNIV_SQL_NULL:
|
||||
break;
|
||||
default:
|
||||
if (trx_undo_left(undo_page, ptr) < flen) {
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
ut_memcpy(ptr, dfield_get_data(field), flen);
|
||||
memcpy(ptr, dfield_get_data(field), flen);
|
||||
ptr += flen;
|
||||
}
|
||||
}
|
||||
|
@ -981,7 +983,7 @@ trx_undo_page_report_modify(
|
|||
return(0);
|
||||
}
|
||||
|
||||
ut_memcpy(ptr, field, flen);
|
||||
memcpy(ptr, field, flen);
|
||||
ptr += flen;
|
||||
}
|
||||
}
|
||||
|
@ -1123,7 +1125,7 @@ trx_undo_page_report_modify(
|
|||
return(0);
|
||||
}
|
||||
|
||||
ut_memcpy(ptr, field, flen);
|
||||
memcpy(ptr, field, flen);
|
||||
ptr += flen;
|
||||
}
|
||||
|
||||
|
@ -1149,7 +1151,7 @@ trx_undo_page_report_modify(
|
|||
return(0);
|
||||
}
|
||||
|
||||
ut_memcpy(ptr, field, flen);
|
||||
memcpy(ptr, field, flen);
|
||||
ptr += flen;
|
||||
}
|
||||
}
|
||||
|
@ -1305,7 +1307,7 @@ trx_undo_page_report_modify(
|
|||
return(0);
|
||||
}
|
||||
|
||||
ut_memcpy(ptr, field, flen);
|
||||
memcpy(ptr, field, flen);
|
||||
ptr += flen;
|
||||
}
|
||||
|
||||
|
@ -1391,14 +1393,17 @@ already_logged:
|
|||
|
||||
ptr += mach_write_compressed(ptr, flen);
|
||||
|
||||
if (flen != UNIV_SQL_NULL) {
|
||||
switch (flen) {
|
||||
case 0: case UNIV_SQL_NULL:
|
||||
break;
|
||||
default:
|
||||
if (trx_undo_left(undo_page, ptr)
|
||||
< flen) {
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
ut_memcpy(ptr, field, flen);
|
||||
memcpy(ptr, field, flen);
|
||||
ptr += flen;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue