Skip to content

Commit

Permalink
Merge pull request #62 from OleksandrKvl/OleksandrKvl/more-cursor-checks
Browse files Browse the repository at this point in the history
  • Loading branch information
OleksandrKvl committed Jul 9, 2024
2 parents b1c45d7 + ff1e283 commit 874a565
Show file tree
Hide file tree
Showing 5 changed files with 418 additions and 82 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 1.4.0

- added checks to protect against using cursor accessors in a wrong order

---

# 1.3.0

- fixed optional built-in types macro.
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.11)

project(sbepp
VERSION 1.3.0
VERSION 1.4.0
LANGUAGES CXX
)

Expand Down
124 changes: 102 additions & 22 deletions sbepp/src/sbepp/sbepp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -862,8 +862,12 @@ class cursor
SBEPP_CPP20_CONSTEXPR T get_value(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (ptr + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, sizeof(U));
T res{detail::get_primitive<U, E>(ptr + offset)};
ptr += offset + sizeof(U);
Expand All @@ -874,9 +878,13 @@ class cursor
SBEPP_CPP20_CONSTEXPR void set_value(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/,
const std::size_t absolute_offset,
const T value) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (ptr + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, sizeof(T));
detail::set_primitive<E>(ptr + offset, value);
ptr += offset + sizeof(T);
Expand All @@ -886,8 +894,12 @@ class cursor
SBEPP_CPP20_CONSTEXPR T get_last_value(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (ptr + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, sizeof(U));
auto res = T{detail::get_primitive<U, E>(ptr + offset)};
ptr = view(detail::get_level_tag{})
Expand All @@ -899,9 +911,13 @@ class cursor
SBEPP_CPP20_CONSTEXPR void set_last_value(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/,
const std::size_t absolute_offset,
const T value) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (ptr + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, sizeof(T));
detail::set_primitive<E>(ptr + offset, value);
ptr = view(detail::get_level_tag{})
Expand All @@ -912,8 +928,12 @@ class cursor
SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (ptr + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, 0);
Res res{ptr + offset, view(detail::end_ptr_tag{})};
ptr += offset + res(detail::size_bytes_tag{});
Expand All @@ -924,8 +944,12 @@ class cursor
SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (ptr + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, 0);
Res res{ptr + offset, view(detail::end_ptr_tag{})};
ptr = view(detail::get_level_tag{})
Expand Down Expand Up @@ -957,8 +981,10 @@ class cursor
template<typename ResView, typename View, typename Getter>
SBEPP_CPP20_CONSTEXPR ResView
get_group_view(const View view, Getter&& /*getter*/) noexcept
get_group_view(const View view, Getter&& getter) noexcept
{
SBEPP_ASSERT(
(getter()(detail::addressof_tag{}) == ptr) && "Wrong cursor value");
ResView res{ptr, view(detail::end_ptr_tag{})};
auto header = res(detail::get_header_tag{});
ptr += header(detail::size_bytes_tag{});
Expand All @@ -967,8 +993,10 @@ class cursor
template<typename ResView, typename View, typename Getter>
SBEPP_CPP20_CONSTEXPR ResView
get_data_view(const View view, Getter&& /*getter*/) noexcept
get_data_view(const View view, Getter&& getter) noexcept
{
SBEPP_ASSERT(
(getter()(detail::addressof_tag{}) == ptr) && "Wrong cursor value");
ResView res{ptr, view(detail::end_ptr_tag{})};
ptr += res(detail::size_bytes_tag{});
return res;
Expand Down Expand Up @@ -1277,8 +1305,12 @@ class dont_move_cursor_wrapper
SBEPP_CPP20_CONSTEXPR T get_value(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (cursor->pointer() + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(
cursor->pointer(), view(end_ptr_tag{}), offset, sizeof(U));
return T{get_primitive<U, E>(cursor->pointer() + offset)};
Expand All @@ -1288,9 +1320,13 @@ class dont_move_cursor_wrapper
SBEPP_CPP20_CONSTEXPR void set_value(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/,
const std::size_t absolute_offset,
const T value) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (cursor->pointer() + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(
cursor->pointer(), view(end_ptr_tag{}), offset, sizeof(T));
set_primitive<E>(cursor->pointer() + offset, value);
Expand All @@ -1300,8 +1336,12 @@ class dont_move_cursor_wrapper
SBEPP_CPP20_CONSTEXPR T get_last_value(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (cursor->pointer() + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(
cursor->pointer(), view(end_ptr_tag{}), offset, sizeof(U));
return T{get_primitive<U, E>(cursor->pointer() + offset)};
Expand All @@ -1311,9 +1351,13 @@ class dont_move_cursor_wrapper
SBEPP_CPP20_CONSTEXPR void set_last_value(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/,
const std::size_t absolute_offset,
const T value) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (cursor->pointer() + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(
cursor->pointer(), view(end_ptr_tag{}), offset, sizeof(T));
set_primitive<E>(cursor->pointer() + offset, value);
Expand All @@ -1323,8 +1367,12 @@ class dont_move_cursor_wrapper
SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (cursor->pointer() + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
return {cursor->pointer() + offset, view(end_ptr_tag{})};
}
Expand All @@ -1333,8 +1381,12 @@ class dont_move_cursor_wrapper
SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (cursor->pointer() + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
return {cursor->pointer() + offset, view(end_ptr_tag{})};
}
Expand All @@ -1361,15 +1413,21 @@ class dont_move_cursor_wrapper
template<typename ResView, typename View, typename Getter>
SBEPP_CPP20_CONSTEXPR ResView
get_group_view(const View view, Getter&& /*getter*/) noexcept
get_group_view(const View view, Getter&& getter) noexcept
{
SBEPP_ASSERT(
(getter()(detail::addressof_tag{}) == cursor->pointer())
&& "Wrong cursor value");
return {cursor->pointer(), view(end_ptr_tag{})};
}
template<typename ResView, typename View, typename Getter>
SBEPP_CPP20_CONSTEXPR ResView
get_data_view(const View view, Getter&& /*getter*/) noexcept
get_data_view(const View view, Getter&& getter) noexcept
{
SBEPP_ASSERT(
(getter()(detail::addressof_tag{}) == cursor->pointer())
&& "Wrong cursor value");
return {cursor->pointer(), view(end_ptr_tag{})};
}
Expand Down Expand Up @@ -1397,8 +1455,12 @@ class skip_cursor_wrapper
SBEPP_CPP20_CONSTEXPR void get_value(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (cursor->pointer() + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(
cursor->pointer(), view(end_ptr_tag{}), offset, sizeof(U));
cursor->pointer() += offset + sizeof(U);
Expand All @@ -1408,8 +1470,12 @@ class skip_cursor_wrapper
SBEPP_CPP20_CONSTEXPR void get_last_value(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (cursor->pointer() + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(
cursor->pointer(), view(end_ptr_tag{}), offset, sizeof(U));
cursor->pointer() =
Expand All @@ -1420,8 +1486,12 @@ class skip_cursor_wrapper
SBEPP_CPP20_CONSTEXPR void get_static_field_view(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (cursor->pointer() + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
Res res{cursor->pointer(), view(end_ptr_tag{})};
cursor->pointer() += offset + res(size_bytes_tag{});
Expand All @@ -1431,8 +1501,12 @@ class skip_cursor_wrapper
SBEPP_CPP20_CONSTEXPR void get_last_static_field_view(
const View view,
const std::size_t offset,
const std::size_t /*absolute_offset*/) noexcept
const std::size_t absolute_offset) noexcept
{
SBEPP_ASSERT(
((view(detail::addressof_tag{}) + absolute_offset)
== (cursor->pointer() + offset))
&& "Wrong cursor value");
SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
cursor->pointer() =
view(get_level_tag{}) + view(get_block_length_tag{});
Expand All @@ -1458,16 +1532,22 @@ class skip_cursor_wrapper
template<typename ResView, typename View, typename Getter>
SBEPP_CPP20_CONSTEXPR void
get_group_view(const View view, Getter&& /*getter*/) noexcept
get_group_view(const View view, Getter&& getter) noexcept
{
SBEPP_ASSERT(
(getter()(detail::addressof_tag{}) == cursor->pointer())
&& "Wrong cursor value");
ResView res{cursor->pointer(), view(end_ptr_tag{})};
cursor->pointer() += res(size_bytes_tag{});
}
template<typename ResView, typename View, typename Getter>
SBEPP_CPP20_CONSTEXPR void
get_data_view(const View view, Getter&& /*getter*/) noexcept
get_data_view(const View view, Getter&& getter) noexcept
{
SBEPP_ASSERT(
(getter()(detail::addressof_tag{}) == cursor->pointer())
&& "Wrong cursor value");
ResView res{cursor->pointer(), view(end_ptr_tag{})};
cursor->pointer() += res(size_bytes_tag{});
}
Expand Down
28 changes: 28 additions & 0 deletions test/schemas/test_schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -501,4 +501,32 @@
<data name="varData" id="9" type="varDataEncoding"/>
<data name="varStr" id="10" type="varStrEncoding"/>
</sbe:message>

<!-- cursor value checks -->
<sbe:message name="msg29" id="29">
<field name="number" id="1" type="uint32_req"/>
<field name="array" id="2" type="str128"/>
<field name="enumeration" id="3" type="numbers_enum"/>
<field name="set" id="4" type="options_set"/>
<field name="composite" id="5" type="composite_a"/>

<!-- cursor is always initialized from scratch for the first group/data
so we need to introduce the extra group before the target one -->
<group name="first_group" id="60"/>

<group name="group" id="6">
<field name="number" id="1" type="uint32_req"/>
<field name="array" id="2" type="str128"/>
<field name="enumeration" id="3" type="numbers_enum"/>
<field name="set" id="4" type="options_set"/>
<field name="composite" id="5" type="composite_a"/>

<group name="first_group" id="60"/>
<group name="group" id="6"/>

<data name="data" id="7" type="varDataEncoding"/>
</group>

<data name="data" id="7" type="varDataEncoding"/>
</sbe:message>
</sbe:messageSchema>
Loading

0 comments on commit 874a565

Please sign in to comment.