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:
parent
bbd49251cf
commit
99747e092f
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue