Skip to content

Add string sanitization test #790

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/fast_io_core_impl/operations/writeimpl/basis.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ inline constexpr void write_all_impl(outstmtype outsm, typename outstmtype::outp
::std::ptrdiff_t bfddiff{ed - curr};
::std::ptrdiff_t itdiff{last - first};
if (itdiff < bfddiff)
#if __has_cpp_attribute(__gnu__::__may_alias__)
#if __has_cpp_attribute(likely)
[[likely]]
#endif
{
Expand Down Expand Up @@ -542,7 +542,7 @@ inline constexpr ::std::byte const *write_some_bytes_impl(outstmtype outsm, ::st
::std::ptrdiff_t bfddiff{ed - curr};
::std::ptrdiff_t itdiff{last - first};
if (itdiff < bfddiff)
#if __has_cpp_attribute(__gnu__::__may_alias__)
#if __has_cpp_attribute(likely)
[[likely]]
#endif
{
Expand Down
86 changes: 85 additions & 1 deletion include/fast_io_unit/string_impl/msvc_stl.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,95 @@ inline constexpr decltype(auto) hack_scary_val(::std::basic_string<elem, traits,
__builtin_offsetof(model_t, _Mypair) + __builtin_offsetof(compress_pair_type, _Myval2));
}

#ifdef _ACTIVATE_STRING_ANNOTATION
/*
https://github.com/microsoft/STL/blob/a357ff1750d3f6dffd54b10d537e93e0accfcc92/stl/inc/xstring#L617
*/

template <typename elem, typename traits, typename alloc>
inline _CONSTEXPR20 void msvc_stl_xstring_Apply_annotation(::std::basic_string<elem, traits, alloc>::value_type const *const _First,
::std::basic_string<elem, traits, alloc>::size_type const _Capacity,
::std::basic_string<elem, traits, alloc>::size_type const _Old_size,
::std::basic_string<elem, traits, alloc>::size_type const _New_size) noexcept
{
#if _HAS_CXX20
if (_STD is_constant_evaluated())
{
return;
}
#endif // _HAS_CXX20
// Don't annotate small strings; only annotate on the heap.
if (_Capacity <= _Small_string_capacity || !_Asan_string_should_annotate)
{
return;
}

// Note that `_Capacity`, `_Old_size`, and `_New_size` do not include the null terminator
void const *const _End = _First + _Capacity + 1;
void const *const _Old_last = _First + _Old_size + 1;
void const *const _New_last = _First + _New_size + 1;

constexpr bool _Large_string_always_asan_aligned =
(_Container_allocation_minimum_asan_alignment<::std::basic_string<elem, traits, alloc>>) >= _Asan_granularity;

// for the non-aligned buffer options, the buffer must always have size >= 9 bytes,
// so it will always end at least one shadow memory section.

_Asan_aligned_pointers _Aligned;
if constexpr (_Large_string_always_asan_aligned)
{
_Aligned = {_First, _STD _Get_asan_aligned_after(_End)};
}
else
{
_Aligned = _STD _Get_asan_aligned_first_end(_First, _End);
}
void const *const _Old_fixed = _Aligned._Clamp_to_end(_Old_last);
void const *const _New_fixed = _Aligned._Clamp_to_end(_New_last);

// --- always aligned case ---
// old state:
// [_First, _Old_last) valid
// [_Old_last, asan_aligned_after(_End)) poison
// new state:
// [_First, _New_last) valid
// [_New_last, asan_aligned_after(_End)) poison

// --- sometimes non-aligned case ---
// old state:
// [_Aligned._First, _Old_fixed) valid
// [_Old_fixed, _Aligned._End) poison
// [_Aligned._End, _End) valid
// new state:
// [_Aligned._First, _New_fixed) valid
// [_New_fixed, _Aligned._End) poison
// [_Aligned._End, _End) valid
_CSTD __sanitizer_annotate_contiguous_container(_Aligned._First, _Aligned._End, _Old_fixed, _New_fixed);
}

template <typename elem, typename traits, typename alloc>
inline _CONSTEXPR20 void msvc_stl_xstring_Modify_annotation(T &_My_data,
::std::basic_string<elem, traits, alloc>::size_type const _Old_size,
::std::basic_string<elem, traits, alloc>::size_type const _New_size) const noexcept
{
if (_Old_size == _New_size)
{
return;
}

::fast_io::details::string_hack::msvc_stl_xstring_Apply_annotation(_My_data._Myptr(), _My_data._Myres, _Old_size, _New_size);
}
#endif

template <typename T>
inline constexpr void set_end_ptr(T &str, typename T::value_type *ptr) noexcept
{
decltype(auto) scv{hack_scary_val(str)};
scv._Mysize = static_cast<::std::size_t>(ptr - str.data());
::std::size_t newsize{static_cast<::std::size_t>(ptr - str.data())};
#ifdef _ACTIVATE_STRING_ANNOTATION
::fast_io::details::string_hack::sanitizer_annotate_contiguous_container(scv, scv._Mysize, newsize);
#endif
scv._Mysize = newsize;
}

template <typename T>
Expand Down
2 changes: 2 additions & 0 deletions tests/0034.string/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_executable(stringtest stringtest.cc)
add_test(stringtest stringtest)
8 changes: 8 additions & 0 deletions tests/0034.string/stringtest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <string>
#include <fast_io.h>

int main()
{
::std::string str("asfasfjaspofjaspofajsfpoasfsaf");
::fast_io::details::string_hack::set_end_ptr(str, str.data() + 5); // resize to 5
}
3 changes: 2 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_EXTENSIONS off)
add_subdirectory(tests/0002.printscan)
add_subdirectory(tests/0026.container)
add_subdirectory(tests/0033.legacy)
add_subdirectory(tests/0033.legacy)
add_subdirectory(tests/0034.string)
Loading