diff --git a/stl/inc/xstring b/stl/inc/xstring index ea4393dae3d..6d5954ea93f 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -2418,6 +2418,10 @@ public: [](_Elem* const _New_ptr, const _Elem* const _Old_ptr, const size_type _Old_size) _STATIC_CALL_OPERATOR { _Traits::copy(_New_ptr, _Old_ptr, _Old_size + 1); }); + // `_Reallocate_grow_by` calls `_ASAN_STRING_CREATE` assuming that the string + // has size (initialized memory) equal to its new capacity (allocated memory). + // This is not true for the `reserve` method, so we modify the ASan annotation. + _ASAN_STRING_MODIFY(*this, _Mypair._Myval2._Mysize, _Old_size); _Mypair._Myval2._Mysize = _Old_size; } @@ -2442,6 +2446,10 @@ public: [](_Elem* const _New_ptr, const _Elem* const _Old_ptr, const size_type _Old_size) _STATIC_CALL_OPERATOR { _Traits::copy(_New_ptr, _Old_ptr, _Old_size + 1); }); + // `_Reallocate_grow_by` calls `_ASAN_STRING_CREATE` assuming that the string + // has size (initialized memory) equal to its new capacity (allocated memory). + // This is not true for the `reserve` method, so we modify the ASan annotation. + _ASAN_STRING_MODIFY(*this, _Mypair._Myval2._Mysize, _Old_size); _Mypair._Myval2._Mysize = _Old_size; return; } 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 5d869884177..e8bf4d30c3e 100644 --- a/tests/std/tests/GH_002030_asan_annotate_string/test.cpp +++ b/tests/std/tests/GH_002030_asan_annotate_string/test.cpp @@ -20,6 +20,8 @@ #include #include #include + +#include #if _HAS_CXX17 #include #endif // _HAS_CXX17 @@ -1917,17 +1919,32 @@ void test_gh_3955() { assert(s == t); } -int main() { - run_allocator_matrix(); +void test_gh_5251() { + // GH-5251 : ASan annotations do not prevent writing to allocated + // but uninitialized basic_string memory + string myString; + myString.reserve(100); + char* myData = &myString[0]; + myData[50] = 'A'; // ASan should fire! +} + +int main(int argc, char* argv[]) { + std_testing::death_test_executive exec([] { + run_allocator_matrix(); #ifdef __cpp_char8_t - run_allocator_matrix(); + run_allocator_matrix(); #endif // __cpp_char8_t - run_allocator_matrix(); - run_allocator_matrix(); - run_allocator_matrix(); - - test_DevCom_10116361(); - test_DevCom_10109507(); - test_gh_3883(); - test_gh_3955(); + run_allocator_matrix(); + run_allocator_matrix(); + run_allocator_matrix(); + + test_DevCom_10116361(); + test_DevCom_10109507(); + test_gh_3883(); + test_gh_3955(); + }); +#ifdef __SANITIZE_ADDRESS__ + exec.add_death_tests({test_gh_5251}); +#endif // ASan instrumentation enabled + return exec.run(argc, argv); }