Skip to content

Commit

Permalink
STL Hardening (#5274)
Browse files Browse the repository at this point in the history
  • Loading branch information
StephanTLavavej authored Feb 21, 2025
1 parent dfbe5ea commit dfdccda
Show file tree
Hide file tree
Showing 53 changed files with 1,203 additions and 416 deletions.
18 changes: 11 additions & 7 deletions stl/inc/__msvc_string_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1379,8 +1379,8 @@ class basic_string_view { // wrapper for any kind of contiguous character buffer
constexpr basic_string_view(
_In_reads_(_Count) const const_pointer _Cts, const size_type _Count) noexcept // strengthened
: _Mydata(_Cts), _Mysize(_Count) {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(_Count == 0 || _Cts, "non-zero size null string_view");
#if _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Count == 0 || _Cts, "cannot construct a string_view from a null pointer and a non-zero size");
#endif
}

Expand Down Expand Up @@ -1474,7 +1474,7 @@ class basic_string_view { // wrapper for any kind of contiguous character buffer
}

_NODISCARD constexpr const_reference operator[](const size_type _Off) const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_BASIC_STRING_VIEW || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Off < _Mysize, "string_view subscript out of range");
#endif

Expand All @@ -1489,31 +1489,35 @@ class basic_string_view { // wrapper for any kind of contiguous character buffer
}

_NODISCARD constexpr const_reference front() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_BASIC_STRING_VIEW || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Mysize != 0, "front() called on empty string_view");
#endif

return _Mydata[0];
}

_NODISCARD constexpr const_reference back() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_BASIC_STRING_VIEW || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Mysize != 0, "back() called on empty string_view");
#endif

return _Mydata[_Mysize - 1];
}

constexpr void remove_prefix(const size_type _Count) noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_BASIC_STRING_VIEW || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Mysize >= _Count, "cannot remove_prefix() larger than string_view size");
#endif

_Mydata += _Count;
_Mysize -= _Count;
}

constexpr void remove_suffix(const size_type _Count) noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_BASIC_STRING_VIEW || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Mysize >= _Count, "cannot remove_suffix() larger than string_view size");
#endif

_Mysize -= _Count;
}

Expand Down
16 changes: 8 additions & 8 deletions stl/inc/array
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ public:
}

_NODISCARD _CONSTEXPR17 reference operator[](_In_range_(<, _Size) size_type _Pos) noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Pos < _Size, "array subscript out of range");
#endif

Expand All @@ -540,7 +540,7 @@ public:

_NODISCARD constexpr const_reference operator[](_In_range_(<, _Size) size_type _Pos) const noexcept
/* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Pos < _Size, "array subscript out of range");
#endif

Expand Down Expand Up @@ -707,47 +707,47 @@ public:
}

_NODISCARD reference operator[](size_type) noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0
_STL_REPORT_ERROR("array<T, 0> subscript is invalid");
#endif

return *data();
}

_NODISCARD const_reference operator[](size_type) const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0
_STL_REPORT_ERROR("array<T, 0> subscript is invalid");
#endif

return *data();
}

_NODISCARD reference front() noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0
_STL_REPORT_ERROR("array<T, 0>::front() is invalid");
#endif

return *data();
}

_NODISCARD const_reference front() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0
_STL_REPORT_ERROR("array<T, 0>::front() is invalid");
#endif

return *data();
}

_NODISCARD reference back() noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0
_STL_REPORT_ERROR("array<T, 0>::back() is invalid");
#endif

return *data();
}

_NODISCARD const_reference back() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_ARRAY || _ITERATOR_DEBUG_LEVEL != 0
_STL_REPORT_ERROR("array<T, 0>::back() is invalid");
#endif

Expand Down
18 changes: 8 additions & 10 deletions stl/inc/bitset
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,6 @@ public:
};

private:
static constexpr void _Validate(const size_t _Pos) noexcept { // verify that _Pos is within bounds
#if _ITERATOR_DEBUG_LEVEL == 0
(void) _Pos;
#else // ^^^ _ITERATOR_DEBUG_LEVEL == 0 / _ITERATOR_DEBUG_LEVEL != 0 vvv
_STL_VERIFY(_Pos < _Bits, "bitset subscript out of range");
#endif // ^^^ _ITERATOR_DEBUG_LEVEL != 0 ^^^
}

constexpr bool _Subscript(size_t _Pos) const noexcept {
return (_Array[_Pos / _Bitsperword] & (_Ty{1} << _Pos % _Bitsperword)) != 0;
}
Expand All @@ -133,12 +125,18 @@ private:

public:
_NODISCARD constexpr bool operator[](const size_t _Pos) const noexcept /* strengthened */ {
_Validate(_Pos);
#if _MSVC_STL_HARDENING_BITSET || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Pos < _Bits, "bitset subscript out of range");
#endif

return _Subscript(_Pos);
}

_NODISCARD _CONSTEXPR23 reference operator[](const size_t _Pos) noexcept /* strengthened */ {
_Validate(_Pos);
#if _MSVC_STL_HARDENING_BITSET || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Pos < _Bits, "bitset subscript out of range");
#endif

return reference(*this, _Pos);
}

Expand Down
51 changes: 19 additions & 32 deletions stl/inc/deque
Original file line number Diff line number Diff line change
Expand Up @@ -1063,15 +1063,15 @@ public:
}

_NODISCARD const_reference operator[](size_type _Pos) const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Pos < _Mysize(), "deque subscript out of range");
#endif

return _Subscript(_Pos);
}

_NODISCARD reference operator[](size_type _Pos) noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(_Pos < _Mysize(), "deque subscript out of range");
#endif

Expand All @@ -1095,31 +1095,31 @@ public:
}

_NODISCARD reference front() noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(!empty(), "front() called on empty deque");
#endif

return _Subscript(0);
}

_NODISCARD const_reference front() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(!empty(), "front() called on empty deque");
#endif

return _Subscript(0);
}

_NODISCARD reference back() noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(!empty(), "back() called on empty deque");
#endif

return _Subscript(_Mysize() - 1);
}

_NODISCARD const_reference back() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(!empty(), "back() called on empty deque");
#endif

Expand Down Expand Up @@ -1473,47 +1473,34 @@ private:

public:
void pop_front() noexcept /* strengthened */ {
#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(!empty(), "pop_front() called on empty deque");
#endif

#if _ITERATOR_DEBUG_LEVEL == 2
if (empty()) {
_STL_REPORT_ERROR("pop_front() called on empty deque");
} else { // something to erase, do it
_Orphan_off(_Myoff());
_Alty_traits::destroy(_Getal(), _Get_data()._Address_subscript(_Myoff()));
if (--_Mysize() == 0) {
_Myoff() = 0;
} else {
++_Myoff();
}
}
#else // ^^^ _ITERATOR_DEBUG_LEVEL == 2 / _ITERATOR_DEBUG_LEVEL < 2 vvv
_Orphan_off(_Myoff());
#endif
_Alty_traits::destroy(_Getal(), _Get_data()._Address_subscript(_Myoff()));
if (--_Mysize() == 0) {
_Myoff() = 0;
} else {
++_Myoff();
}
#endif // ^^^ _ITERATOR_DEBUG_LEVEL < 2 ^^^
}

void pop_back() noexcept /* strengthened */ {
#if _ITERATOR_DEBUG_LEVEL == 2
if (empty()) {
_STL_REPORT_ERROR("pop_back() called on empty deque");
} else { // something to erase, do it
size_type _Newoff = _Myoff() + _Mysize() - 1;
_Orphan_off(_Newoff);
_Alty_traits::destroy(_Getal(), _Get_data()._Address_subscript(_Newoff));
if (--_Mysize() == 0) {
_Myoff() = 0;
}
}
#else // ^^^ _ITERATOR_DEBUG_LEVEL == 2 / _ITERATOR_DEBUG_LEVEL < 2 vvv
#if _MSVC_STL_HARDENING_DEQUE || _ITERATOR_DEBUG_LEVEL != 0
_STL_VERIFY(!empty(), "pop_back() called on empty deque");
#endif

size_type _Newoff = _Myoff() + _Mysize() - 1;
#if _ITERATOR_DEBUG_LEVEL == 2
_Orphan_off(_Newoff);
#endif
_Alty_traits::destroy(_Getal(), _Get_data()._Address_subscript(_Newoff));
if (--_Mysize() == 0) {
_Myoff() = 0;
}
#endif // ^^^ _ITERATOR_DEBUG_LEVEL < 2 ^^^
}

iterator erase(const_iterator _Where) noexcept(is_nothrow_move_assignable_v<value_type>) /* strengthened */ {
Expand Down
Loading

0 comments on commit dfdccda

Please sign in to comment.