Test ASAN SSO string copies; improve `basic_string::_Construct` preconditions (#3039)

Co-authored-by: Stephan T. Lavavej <stl@microsoft.com>
This commit is contained in:
Casey Carter 2022-08-22 14:18:38 -07:00 коммит произвёл GitHub
Родитель ff29e7a6d0
Коммит ad18417c3e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 28 добавлений и 4 удалений

Просмотреть файл

@ -2696,7 +2696,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>);
@ -2708,7 +2710,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);
@ -2718,10 +2719,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);

Просмотреть файл

@ -19,6 +19,7 @@
#include <cstring>
#include <iterator>
#include <memory>
#include <new>
#include <sstream>
#include <string>
#if _HAS_CXX17
@ -1822,6 +1823,28 @@ void run_allocator_matrix() {
run_custom_allocator_matrix<CharType, implicit_allocator>();
}
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<char>();
#ifdef __cpp_char8_t
@ -1830,6 +1853,8 @@ int main() {
run_allocator_matrix<char16_t>();
run_allocator_matrix<char32_t>();
run_allocator_matrix<wchar_t>();
test_DevCom_10116361();
}
#endif // TRANSITION, VSO-1586016