[libcxx-commits] [libcxx] [libc++][hardening] Add checks to `forward_list` element access. (PR #120858)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Dec 21 14:55:43 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Konstantin Varlamov (var-const)
<details>
<summary>Changes</summary>
In our implementation, failing these checks would result in a null
pointer access rather than an out-of-bounds access.
---
Full diff: https://github.com/llvm/llvm-project/pull/120858.diff
2 Files Affected:
- (modified) libcxx/include/forward_list (+9-2)
- (added) libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp (+45)
``````````diff
diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list
index c1ab155d5a133e..aa603da84f856e 100644
--- a/libcxx/include/forward_list
+++ b/libcxx/include/forward_list
@@ -766,8 +766,14 @@ public:
return std::min<size_type>(__node_traits::max_size(this->__alloc_), numeric_limits<difference_type>::max());
}
- _LIBCPP_HIDE_FROM_ABI reference front() { return __base::__before_begin()->__next_->__get_value(); }
- _LIBCPP_HIDE_FROM_ABI const_reference front() const { return __base::__before_begin()->__next_->__get_value(); }
+ _LIBCPP_HIDE_FROM_ABI reference front() {
+ _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list");
+ return __base::__before_begin()->__next_->__get_value();
+ }
+ _LIBCPP_HIDE_FROM_ABI const_reference front() const {
+ _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::front called on an empty list");
+ return __base::__before_begin()->__next_->__get_value();
+ }
# ifndef _LIBCPP_CXX03_LANG
# if _LIBCPP_STD_VER >= 17
@@ -1085,6 +1091,7 @@ void forward_list<_Tp, _Alloc>::push_front(const value_type& __v) {
template <class _Tp, class _Alloc>
void forward_list<_Tp, _Alloc>::pop_front() {
+ _LIBCPP_ASSERT_NON_NULL(!empty(), "forward_list::pop_front called on an empty list");
__node_pointer __p = __base::__before_begin()->__next_;
__base::__before_begin()->__next_ = __p->__next_;
this->__delete_node(__p);
diff --git a/libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp b/libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp
new file mode 100644
index 00000000000000..e442d75a5904d6
--- /dev/null
+++ b/libcxx/test/libcxx/containers/sequences/forwardlist/assert.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <forward_list>
+
+// Test hardening assertions for std::forward_list.
+
+// REQUIRES: has-unix-headers
+// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
+// UNSUPPORTED: c++03
+// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
+
+#include <forward_list>
+
+#include "check_assertion.h"
+
+int main(int, char**) {
+ { // Default-constructed list.
+ std::forward_list<int> c;
+ const auto& const_c = c;
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "forward_list::front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(const_c.front(), "forward_list::front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_front(), "forward_list::pop_front called on an empty list");
+ }
+
+ { // Non-empty list becomes empty.
+ std::forward_list<int> c;
+ const auto& const_c = c;
+ c.push_front(1);
+
+ (void)c.front(); // Check that there's no assertion on valid access.
+ (void)const_c.front(); // Check that there's no assertion on valid access.
+ c.pop_front();
+ TEST_LIBCPP_ASSERT_FAILURE(c.pop_front(), "forward_list::pop_front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(c.front(), "forward_list::front called on an empty list");
+ TEST_LIBCPP_ASSERT_FAILURE(const_c.front(), "forward_list::front called on an empty list");
+ }
+
+ return 0;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/120858
More information about the libcxx-commits
mailing list