Avoid index truncation in check_explicit_index_range_ref

Split check_index_range to check_index_range+check_index_range_size.
Redirect check_explicit_index_range_ref to check_index_range_size, so
that the index_type is not truncated and then extended.
This commit is contained in:
Kp 2022-04-17 22:27:19 +00:00
parent bbd49251cf
commit 99747e092f
2 changed files with 27 additions and 3 deletions

View file

@ -108,6 +108,11 @@ protected:
template <typename> class Compare = std::less
>
static inline index_type check_index_range(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS index_type, const array_managed_type *);
template <
typename handle_index_range_error,
template <typename> class Compare = std::less
>
static inline index_type check_index_range_size(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS std::size_t, const array_managed_type *);
template <typename handle_index_mismatch, typename handle_index_range_error>
static inline void check_explicit_index_range_ref(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const_reference_type, std::size_t, const array_managed_type &);
template <typename handle_index_mismatch, typename handle_index_range_error>

View file

@ -210,11 +210,30 @@ typename valptridx<managed_type>::index_type valptridx<managed_type>::check_inde
si = static_cast<std::size_t>(i);
else
si = i;
const std::size_t ss = si;
DXX_VALPTRIDX_CHECK(Compare<std::size_t>()(ss, array_size), handle_index_range_error, "invalid index used in array subscript", a, ss);
check_index_range_size<handle_index_range_error, Compare>(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS si, a);
return i;
}
template <typename managed_type>
template <typename handle_index_range_error, template <typename> class Compare>
typename valptridx<managed_type>::index_type valptridx<managed_type>::check_index_range_size(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const std::size_t s, const array_managed_type *const a)
{
DXX_VALPTRIDX_CHECK(Compare<std::size_t>()(s, array_size), handle_index_range_error, "invalid index used in array subscript", a, s);
/* This cast will truncate the value to fit in index_type, which is
* normally smaller than std::size_t. However, truncation is legal
* here, because (1) DXX_VALPTRIDX_CHECK would trap on an index that
* was outside the array size and (2) index_type can represent any
* valid size in the array. Thus, if DXX_VALPTRIDX_CHECK did not
* trap[1], the truncation cannot change the value of the index.
*
* [1] If valptridx was built without index validation, then no trap
* would be issued even for invalid data. Validation-disabled builds
* are permitted to exhibit undefined behavior in cases where the
* validation-enabled build would have trapped.
*/
return static_cast<index_type>(s);
}
template <typename managed_type>
template <typename handle_null_pointer>
void valptridx<managed_type>::check_null_pointer_conversion(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const_pointer_type p)
@ -241,7 +260,7 @@ template <typename handle_index_mismatch, typename handle_index_range_error>
void valptridx<managed_type>::check_explicit_index_range_ref(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const_reference_type &r, std::size_t i, const array_managed_type &a)
{
check_index_match<handle_index_mismatch>(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS r, i, a);
check_index_range<handle_index_range_error>(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS i, &a);
check_index_range_size<handle_index_range_error>(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VARS i, &a);
}
template <typename managed_type>