[libcxx-commits] [libcxx] [libcxx] adds additional checks to RAI containers' `erase` (PR #90919)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu May 2 17:05:38 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Christopher Di Bella (cjdb)
<details>
<summary>Changes</summary>
This ensures that the iterators passed in are in-range for the container. Thanks to @<!-- -->mclow for identifying this opportunity.
---
Full diff: https://github.com/llvm/llvm-project/pull/90919.diff
3 Files Affected:
- (modified) libcxx/include/deque (+9-2)
- (modified) libcxx/include/string (+9-2)
- (modified) libcxx/include/vector (+9-2)
``````````diff
diff --git a/libcxx/include/deque b/libcxx/include/deque
index 3c33e04e9f05f8..2df644cd3d80ea 100644
--- a/libcxx/include/deque
+++ b/libcxx/include/deque
@@ -2372,7 +2372,9 @@ void deque<_Tp, _Allocator>::__move_construct_backward_and_check(
template <class _Tp, class _Allocator>
typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f) {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
- __f != end(), "deque::erase(iterator) called with a non-dereferenceable iterator");
+ __f >= begin(), "deque::erase(iterator) called with an iterator outside of the container's control");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __f < end(), "deque::erase(iterator) called with an iterator outside of the container's control");
size_type __old_sz = size();
size_type __old_start = __start_;
iterator __b = begin();
@@ -2398,7 +2400,12 @@ typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_it
template <class _Tp, class _Allocator>
typename deque<_Tp, _Allocator>::iterator deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) {
- _LIBCPP_ASSERT_VALID_INPUT_RANGE(__f <= __l, "deque::erase(first, last) called with an invalid range");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+ __f <= begin(), "deque::erase(first, last) called with an iterator range starting before 'begin()'");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+ __l <= end(), "deque::erase(first, last) called with an iterator range finishing after 'end()'");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+ __f <= __l, "deque::erase(first, last) called with an invalid range");
size_type __old_sz = size();
size_type __old_start = __start_;
difference_type __n = __l - __f;
diff --git a/libcxx/include/string b/libcxx/include/string
index 4e3dd278c12b0c..3f15e0b766edd8 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -3155,7 +3155,9 @@ template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
- __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator");
+ __pos >= begin(), "string::erase(iterator) called with an iterator outside of the container's control");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __pos < end(), "string::erase(iterator) called with an iterator outside of the container's control");
iterator __b = begin();
size_type __r = static_cast<size_type>(__pos - __b);
erase(__r, 1);
@@ -3165,7 +3167,12 @@ basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) {
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator
basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) {
- _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+ __first >= begin(), "string::erase(first, last) called with an iterator range starting before 'begin()'");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+ __last <= end(), "string::erase(first, last) called with an iterator range finishing after 'end()'");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+ __first <= __last, "string::erase(first, last) called with invalid range");
iterator __b = begin();
size_type __r = static_cast<size_type>(__first - __b);
erase(__r, static_cast<size_type>(__last - __first));
diff --git a/libcxx/include/vector b/libcxx/include/vector
index 976bde9b9048c8..16cb3bab942dd6 100644
--- a/libcxx/include/vector
+++ b/libcxx/include/vector
@@ -1537,7 +1537,9 @@ template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::erase(const_iterator __position) {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
- __position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator");
+ __position >= begin(), "vector::erase(iterator) called with an iterator outside of the container's control");
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __position < end(), "vector::erase(iterator) called with an iterator outside of the container's control");
difference_type __ps = __position - cbegin();
pointer __p = this->__begin_ + __ps;
this->__destruct_at_end(std::move(__p + 1, this->__end_, __p));
@@ -1547,7 +1549,12 @@ vector<_Tp, _Allocator>::erase(const_iterator __position) {
template <class _Tp, class _Allocator>
_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) {
- _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+ __first >= begin(), "vector::erase(first, last) called with an iterator range starting before 'begin()'");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+ __last <= end(), "vector::erase(first, last) called with an iterator range finishing after 'end()'");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(
+ __first <= __last, "vector::erase(first, last) called with invalid range");
pointer __p = this->__begin_ + (__first - begin());
if (__first != __last) {
this->__destruct_at_end(std::move(__p + (__last - __first), this->__end_, __p));
``````````
</details>
https://github.com/llvm/llvm-project/pull/90919
More information about the libcxx-commits
mailing list