Skip to content

Commit ad18417

Browse files
Test ASAN SSO string copies; improve basic_string::_Construct preconditions (#3039)
Co-authored-by: Stephan T. Lavavej <[email protected]>
1 parent ff29e7a commit ad18417

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

stl/inc/xstring

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,7 +2696,9 @@ private:
26962696
enum class _Construct_strategy : uint8_t { _From_char, _From_ptr, _From_string };
26972697
template <_Construct_strategy _Strat, class _Char_or_ptr>
26982698
_CONSTEXPR20 void _Construct(const _Char_or_ptr _Arg, _CRT_GUARDOVERFLOW const size_type _Count) {
2699-
// Pre: *this is in SSO mode; the lifetime of the SSO elements has already begun
2699+
auto& _My_data = _Mypair._Myval2;
2700+
_STL_INTERNAL_CHECK(!_My_data._Large_string_engaged());
2701+
_STL_INTERNAL_CHECK(_STD count(_My_data._Bx._Buf, _My_data._Bx._Buf + _BUF_SIZE, _Elem()) == _BUF_SIZE);
27002702

27012703
if constexpr (_Strat == _Construct_strategy::_From_char) {
27022704
_STL_INTERNAL_STATIC_ASSERT(is_same_v<_Char_or_ptr, _Elem>);
@@ -2708,7 +2710,6 @@ private:
27082710
_Xlen_string(); // result too long
27092711
}
27102712

2711-
auto& _My_data = _Mypair._Myval2;
27122713
auto& _Al = _Getal();
27132714
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al);
27142715
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data);
@@ -2718,10 +2719,8 @@ private:
27182719
_My_data._Myres = _BUF_SIZE - 1;
27192720
if constexpr (_Strat == _Construct_strategy::_From_char) {
27202721
_Traits::assign(_My_data._Bx._Buf, _Count, _Arg);
2721-
_Traits::assign(_My_data._Bx._Buf[_Count], _Elem());
27222722
} else if constexpr (_Strat == _Construct_strategy::_From_ptr) {
27232723
_Traits::move(_My_data._Bx._Buf, _Arg, _Count);
2724-
_Traits::assign(_My_data._Bx._Buf[_Count], _Elem());
27252724
} else { // _Strat == _Construct_strategy::_From_string
27262725
#ifdef _INSERT_STRING_ANNOTATION
27272726
_Traits::move(_My_data._Bx._Buf, _Arg, _Count);

tests/std/tests/GH_002030_asan_annotate_string/test.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <cstring>
2020
#include <iterator>
2121
#include <memory>
22+
#include <new>
2223
#include <sstream>
2324
#include <string>
2425
#if _HAS_CXX17
@@ -1822,6 +1823,28 @@ void run_allocator_matrix() {
18221823
run_custom_allocator_matrix<CharType, implicit_allocator>();
18231824
}
18241825

1826+
void test_DevCom_10116361() {
1827+
// We failed to null-terminate copies of SSO strings with ASAN annotations active.
1828+
#ifdef _WIN64
1829+
constexpr const char* text = "testtest";
1830+
constexpr size_t n = 8;
1831+
#else
1832+
constexpr const char* text = "test";
1833+
constexpr size_t n = 4;
1834+
#endif
1835+
1836+
string s0{text};
1837+
assert(s0.c_str()[n] == '\0');
1838+
1839+
alignas(string) unsigned char space[sizeof(string)];
1840+
memset(space, 0xff, sizeof(space));
1841+
1842+
string& s1 = *::new (&space) string{s0};
1843+
assert(s1.c_str()[n] == '\0');
1844+
1845+
s1.~string();
1846+
}
1847+
18251848
int main() {
18261849
run_allocator_matrix<char>();
18271850
#ifdef __cpp_char8_t
@@ -1830,6 +1853,8 @@ int main() {
18301853
run_allocator_matrix<char16_t>();
18311854
run_allocator_matrix<char32_t>();
18321855
run_allocator_matrix<wchar_t>();
1856+
1857+
test_DevCom_10116361();
18331858
}
18341859
#endif // TRANSITION, VSO-1586016
18351860

0 commit comments

Comments
 (0)