From 41ddc88a80160050b0ac1a51cb258f8918edf9aa Mon Sep 17 00:00:00 2001 From: "Lucas A. M. Magalhaes" Date: Wed, 23 Jun 2021 15:05:50 -0300 Subject: [PATCH] vector: Fix undefined behaviour on realloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On tests listed bellow the reserve method is being called before any allocation on the object therefore realloc being called without any previous allocation. Inside realloc _data is being used with the operator '[]', as it is nullptr at that moment it's an undefined behaviour. This patch simply returns a call to alloc if _data is nullptr. This tests fails on PowerPC with Segmentation Fault because of this issue: segment_vector_array_expsize_assign_exceptions_oom_0_none segment_vector_array_expsize_assign_exceptions_oom_0_memcheck segment_vector_array_expsize_capacity_exceptions_oom_0_none segment_vector_array_expsize_capacity_exceptions_oom_0_memcheck segment_vector_array_expsize_modifiers_exceptions_oom_0_none segment_vector_array_expsize_modifiers_exceptions_oom_0_memcheck segment_vector_vector_expsize_assign_exceptions_oom_0_none segment_vector_vector_expsize_assign_exceptions_oom_0_memcheck segment_vector_vector_expsize_capacity_exceptions_oom_0_none segment_vector_vector_expsize_capacity_exceptions_oom_0_memcheck segment_vector_vector_expsize_modifiers_exceptions_oom_0_none segment_vector_vector_expsize_modifiers_exceptions_oom_0_memcheck segment_vector_vector_fixedsize_assign_exceptions_oom_0_none segment_vector_vector_fixedsize_assign_exceptions_oom_0_memcheck Signed-off-by: Lucas A. M. Magalhães lamm@linux.ibm.com --- include/libpmemobj++/container/vector.hpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/libpmemobj++/container/vector.hpp b/include/libpmemobj++/container/vector.hpp index f430ed50..9810220b 100644 --- a/include/libpmemobj++/container/vector.hpp +++ b/include/libpmemobj++/container/vector.hpp @@ -2362,7 +2362,8 @@ vector::internal_insert(size_type idx, InputIt first, InputIt last) * Private helper function. Must be called during transaction. Allocates new * memory for capacity_new number of elements and copies or moves old elements * to new memory area. If the current size is greater than capacity_new, the - * container is reduced to its first capacity_new elements. + * container is reduced to its first capacity_new elements. If was never + * allocated behaves as an alloc call. * * param[in] capacity_new new capacity. * @@ -2381,6 +2382,13 @@ vector::realloc(size_type capacity_new) { assert(pmemobj_tx_stage() == TX_STAGE_WORK); + /* + * If _data == nullptr this object has never allocated any memory + * so we need to behave as alloc instead. + */ + if (_data == nullptr) + return alloc(capacity_new); + /* * XXX: future optimization: we don't have to snapshot data * which we will not overwrite -- 2.27.0