From f5b2c7ba743f17ac5dd75f552cd9271397a13f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 6 Mar 2022 22:37:41 +0100 Subject: [PATCH] Fixes #214: ("string is not properly null-terminated in assignments") --- doc/container.qbk | 1 + include/boost/container/string.hpp | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/doc/container.qbk b/doc/container.qbk index 6c958c5..b44db8f 100644 --- a/doc/container.qbk +++ b/doc/container.qbk @@ -1347,6 +1347,7 @@ use [*Boost.Container]? There are several reasons for that: * [@https://github.com/boostorg/container/issues/204 GitHub #204: ['"Inconsistent noexcept-ness of static_vector::reserve"]]. * [@https://github.com/boostorg/container/issues/206 GitHub #206: ['"operator-> on static_vector::iterator causes cast alignment warning"]]. * [@https://github.com/boostorg/container/issues/207 GitHub #207: ['"boost.vector doesn't work with common_iterator"]]. + * [@https://github.com/boostorg/container/issues/214 GitHub #214: ['"string is not properly null-terminated in assignments"]]. [endsect] diff --git a/include/boost/container/string.hpp b/include/boost/container/string.hpp index 7b4e572..fbe0986 100644 --- a/include/boost/container/string.hpp +++ b/include/boost/container/string.hpp @@ -1806,16 +1806,17 @@ class basic_string if(enough_capacity){ const size_type elems_after = old_size - size_type(p - old_start); const size_type old_length = old_size; + size_type new_size = 0; if (elems_after >= n) { const pointer pointer_past_last = old_start + difference_type(old_size + 1u); priv_uninitialized_copy(old_start + difference_type(old_size - n + 1u), pointer_past_last, pointer_past_last); - this->priv_size(old_size+n); Traits::move(const_cast(boost::movelib::to_raw_pointer(p + difference_type(n))), boost::movelib::to_raw_pointer(p), (elems_after - n) + 1u); - this->priv_copy(first, last, const_cast(boost::movelib::to_raw_pointer(p))); + (priv_copy)(first, last, const_cast(boost::movelib::to_raw_pointer(p))); + new_size = old_size + n; } else { ForwardIter mid = first; @@ -1827,9 +1828,11 @@ class basic_string priv_uninitialized_copy (p, const_iterator(old_start + difference_type(old_length + 1u)), old_start + difference_type(newer_size)); - this->priv_size(newer_size + elems_after); - this->priv_copy(first, mid, const_cast(boost::movelib::to_raw_pointer(p))); + (priv_copy)(first, mid, const_cast(boost::movelib::to_raw_pointer(p))); + new_size = newer_size + elems_after; } + this->priv_size(new_size); + this->priv_construct_null(old_start + difference_type(new_size)); } else{ pointer new_start = allocation_ret; @@ -2982,12 +2985,12 @@ class basic_string } } - void priv_construct_null(pointer p) + BOOST_CONTAINER_FORCEINLINE void priv_construct_null(pointer p) { this->construct(p, CharT(0)); } // Helper functions used by constructors. It is a severe error for // any of them to be called anywhere except from within constructors. - void priv_terminate_string() + BOOST_CONTAINER_FORCEINLINE void priv_terminate_string() { this->priv_construct_null(this->priv_end_addr()); } template inline @@ -3037,13 +3040,13 @@ class basic_string } template - void priv_copy(InputIterator first, InputIterator last, OutIterator result) + static void priv_copy(InputIterator first, InputIterator last, OutIterator result) { for ( ; first != last; ++first, ++result) Traits::assign(*result, *first); } - BOOST_CONTAINER_FORCEINLINE void priv_copy(const CharT* first, const CharT* last, CharT* result) + static BOOST_CONTAINER_FORCEINLINE void priv_copy(const CharT* first, const CharT* last, CharT* result) { Traits::copy(result, first, std::size_t(last - first)); } template