diff --git a/stl/inc/xstring b/stl/inc/xstring index 28593f1cca..0aa85d82cd 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -2690,7 +2690,9 @@ private: enum class _Construct_strategy : uint8_t { _From_char, _From_ptr, _From_string }; template <_Construct_strategy _Strat, class _Char_or_ptr> _CONSTEXPR20 void _Construct(const _Char_or_ptr _Arg, _CRT_GUARDOVERFLOW const size_type _Count) { - // Pre: *this is in SSO mode; the lifetime of the SSO elements has already begun + auto& _My_data = _Mypair._Myval2; + _STL_INTERNAL_CHECK(!_My_data._Large_string_engaged()); + _STL_INTERNAL_CHECK(_STD count(_My_data._Bx._Buf, _My_data._Bx._Buf + _BUF_SIZE, _Elem()) == _BUF_SIZE); if constexpr (_Strat == _Construct_strategy::_From_char) { _STL_INTERNAL_STATIC_ASSERT(is_same_v<_Char_or_ptr, _Elem>); @@ -2702,7 +2704,6 @@ private: _Xlen_string(); // result too long } - auto& _My_data = _Mypair._Myval2; auto& _Al = _Getal(); auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al); _Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); @@ -2712,10 +2713,8 @@ private: _My_data._Myres = _BUF_SIZE - 1; if constexpr (_Strat == _Construct_strategy::_From_char) { _Traits::assign(_My_data._Bx._Buf, _Count, _Arg); - _Traits::assign(_My_data._Bx._Buf[_Count], _Elem()); } else if constexpr (_Strat == _Construct_strategy::_From_ptr) { _Traits::move(_My_data._Bx._Buf, _Arg, _Count); - _Traits::assign(_My_data._Bx._Buf[_Count], _Elem()); } else { // _Strat == _Construct_strategy::_From_string #ifdef _INSERT_STRING_ANNOTATION _Traits::move(_My_data._Bx._Buf, _Arg, _Count); diff --git a/tests/std/tests/GH_002030_asan_annotate_string/test.cpp b/tests/std/tests/GH_002030_asan_annotate_string/test.cpp index 0571ae4691..4d2b11aa43 100644 --- a/tests/std/tests/GH_002030_asan_annotate_string/test.cpp +++ b/tests/std/tests/GH_002030_asan_annotate_string/test.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #if _HAS_CXX17 @@ -1822,6 +1823,28 @@ void run_allocator_matrix() { run_custom_allocator_matrix(); } +void test_DevCom_10116361() { + // We failed to null-terminate copies of SSO strings with ASAN annotations active. +#ifdef _WIN64 + constexpr const char* text = "testtest"; + constexpr size_t n = 8; +#else + constexpr const char* text = "test"; + constexpr size_t n = 4; +#endif + + string s0{text}; + assert(s0.c_str()[n] == '\0'); + + alignas(string) unsigned char space[sizeof(string)]; + memset(space, 0xff, sizeof(space)); + + string& s1 = *::new (&space) string{s0}; + assert(s1.c_str()[n] == '\0'); + + s1.~string(); +} + int main() { run_allocator_matrix(); #ifdef __cpp_char8_t @@ -1830,6 +1853,8 @@ int main() { run_allocator_matrix(); run_allocator_matrix(); run_allocator_matrix(); + + test_DevCom_10116361(); } #endif // TRANSITION, VSO-1586016