diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index cbfff7d180..25861bbfcc 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -42,6 +42,7 @@ The Axom project release numbers follow [Semantic Versioning](http://semver.org/ - Updates uberenv submodule to HEAD of main on 28Dec2022 - Updates blt submodule to HEAD of develop on 28Dec2022 - Adds `vcpkg` ports for `RAJA`, `Umpire` with optional `OpenMP` feature for automated Windows build +- Reduce size of `ArrayView::subspan` to prevent accessing invalid memory. ## [Version 0.7.0] - Release date 2022-08-30 diff --git a/src/axom/core/ArrayView.hpp b/src/axom/core/ArrayView.hpp index c91e991ae4..28d8bf3dbf 100644 --- a/src/axom/core/ArrayView.hpp +++ b/src/axom/core/ArrayView.hpp @@ -135,18 +135,27 @@ class ArrayView : public ArrayBase> * \param [in] count The number of elements to include in the subspan, or -1 * to take all elements after offset (default). * - * \return A subspan ArrayView that spans the indices [offsets, offsets + count), - * or [offsets, num_elements) if count == -1. + * \return An ArrayView that spans the indices [offset, offset + count), + * or [offset, num_elements) if count < 0. * - * \pre offset + count <= m_num_elements if count != -1 + * \pre offset + count <= m_num_elements if count < 0 */ template ::type> AXOM_HOST_DEVICE ArrayView subspan(IndexType offset, IndexType count = -1) const { - assert(offset + count <= m_num_elements); + assert(offset >= 0 && offset < m_num_elements); + if(count >= 0) + { + assert(offset + count <= m_num_elements); + } + ArrayView slice = *this; slice.m_data += offset; - if(count != -1) + if(count < 0) + { + slice.m_num_elements -= offset; + } + else { slice.m_num_elements = count; } diff --git a/src/axom/core/tests/core_array.hpp b/src/axom/core/tests/core_array.hpp index d492dd258b..0f4373f07e 100644 --- a/src/axom/core/tests/core_array.hpp +++ b/src/axom/core/tests/core_array.hpp @@ -1931,4 +1931,27 @@ TEST(core_array, checkVariadicCtors) Array arr12(s, s, s); } +//------------------------------------------------------------------------------ + +TEST(core_array, check_subspan_range) +{ + int m = 10; + int n = 3; + int l = 5; + Array arr(m); + + ArrayView arrv1(arr); + EXPECT_EQ(arrv1.size(), arr.size()); + + ArrayView arrv2 = arrv1.subspan(n); + EXPECT_EQ(arrv2.size() + n, arrv1.size()); + EXPECT_EQ(&arrv2[0], &arr[n]); + EXPECT_EQ(&arrv2[arrv2.size() - 1], &arr[arr.size() - 1]); + + ArrayView arrv3 = arrv1.subspan(n, l); + EXPECT_EQ(arrv3.size(), l); + EXPECT_EQ(&arrv3[0], &arr[n]); + EXPECT_EQ(&arrv3[arrv3.size() - 1], &arr[n + l - 1]); +} + } /* end namespace axom */