diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e38b972..66a05f37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Version 159: * Fix typo in release notes * Safe treatment of zero-length string arguments in basic_fields +* Some basic_fields operations now give the strong exception guarantee -------------------------------------------------------------------------------- diff --git a/doc/qbk/09_releases.qbk b/doc/qbk/09_releases.qbk index 95f8fa19..54813141 100644 --- a/doc/qbk/09_releases.qbk +++ b/doc/qbk/09_releases.qbk @@ -77,6 +77,8 @@ to update to the latest Boost release. * ([issue 1026]) Advanced servers support clean shutdown via SIGINT or SIGTERM +* Some basic_fields operations now give the strong exception guarantee + [*Fixes] * Fix "warning: ‘const’ type qualifier on return type has no effect" diff --git a/include/boost/beast/http/impl/fields.ipp b/include/boost/beast/http/impl/fields.ipp index 9d828c80..a07fd0fa 100644 --- a/include/boost/beast/http/impl/fields.ipp +++ b/include/boost/beast/http/impl/fields.ipp @@ -1219,18 +1219,19 @@ realloc_string(string_view& dest, string_view s) auto a = typename beast::detail::allocator_traits< Allocator>::template rebind_alloc< char>(this->member()); - if(! dest.empty()) - { - a.deallocate(const_cast( - dest.data()), dest.size()); - dest = {}; - } + char* p = nullptr; if(! s.empty()) { - auto const p = a.allocate(s.size()); + p = a.allocate(s.size()); s.copy(p, s.size()); - dest = {p, s.size()}; } + if(! dest.empty()) + a.deallocate(const_cast( + dest.data()), dest.size()); + if(p) + dest = {p, s.size()}; + else + dest = {}; } template @@ -1247,19 +1248,20 @@ realloc_target( auto a = typename beast::detail::allocator_traits< Allocator>::template rebind_alloc< char>(this->member()); - if(! dest.empty()) - { - a.deallocate(const_cast( - dest.data()), dest.size()); - dest = {}; - } + char* p = nullptr; if(! s.empty()) { - auto const p = a.allocate(1 + s.size()); + p = a.allocate(1 + s.size()); p[0] = ' '; s.copy(p + 1, s.size()); - dest = {p, 1 + s.size()}; } + if(! dest.empty()) + a.deallocate(const_cast( + dest.data()), dest.size()); + if(p) + dest = {p, 1 + s.size()}; + else + dest = {}; } template