2
0
mirror of https://github.com/boostorg/parser.git synced 2026-02-02 09:02:12 +00:00

Correct memory safety issue in converting token iteratos to underlying

iterators.

See #202.
This commit is contained in:
Zach Laine
2024-12-01 20:26:18 -06:00
parent bc6e9e3447
commit 3fd285c014
3 changed files with 20 additions and 20 deletions

View File

@@ -1014,10 +1014,8 @@ namespace boost { namespace parser { namespace detail {
if (!detail::do_trace(flags_))
return;
if constexpr (is_token_iter_v<Iter>) {
auto const initial_first = first_.range_begin();
auto const first = initial_first + (*first_).underlying_position();
auto const last = first_.range_end();
detail::trace_prefix(os, first, last, context_, name_);
detail::trace_prefix(
os, first_.base(), first_.range_end(), context_, name_);
} else {
detail::trace_prefix(os, first_, last_, context_, name_);
}
@@ -1032,14 +1030,10 @@ namespace boost { namespace parser { namespace detail {
scoped_trace_t<DoTrace, Iter, Sentinel, Context, Attribute>::
~scoped_trace_t()
{
if constexpr (is_token_iter_v<Iter>) {
auto const initial_first = first_.range_begin();
auto const first = initial_first + (*first_).underlying_position();
auto const last = first_.range_end();
impl(initial_first, first, last);
} else {
if constexpr (is_token_iter_v<Iter>)
impl(first_.range_begin(), first_.base(), first_.range_end());
else
impl(initial_first_, first_, last_);
}
}
}}}

View File

@@ -192,16 +192,10 @@ namespace boost { namespace parser {
template<typename I, typename S>
auto normalize_iterators_impl(I first, I it, S last)
{
if constexpr (detail::is_token_iter_v<I>) {
auto const underlying_first = it.range_begin();
auto const underlying_it =
underlying_first + (*it).underlying_position();
auto const underlying_last = it.range_end();
return std::tuple(
underlying_first, underlying_it, underlying_last);
} else {
if constexpr (detail::is_token_iter_v<I>)
return std::tuple(it.range_begin(), it.base(), it.range_end());
else
return std::tuple(first, it, last);
}
}
}

View File

@@ -941,6 +941,9 @@ namespace boost { namespace parser {
constexpr token_type const & operator*() const
{
BOOST_PARSER_DEBUG_ASSERT(
token_offset_ - parent_->base_token_offset_ <
(BOOST_PARSER_TOKEN_POSITION_TYPE)parent_->tokens_.size());
return parent_
->tokens_[token_offset_ - parent_->base_token_offset_];
}
@@ -951,6 +954,15 @@ namespace boost { namespace parser {
return token_offset_ == rhs.token_offset_;
}
auto base() const
{
return token_offset_ - parent_->base_token_offset_ ==
(BOOST_PARSER_TOKEN_POSITION_TYPE)
parent_->tokens_.size()
? range_end()
: range_begin() + (**this).underlying_position();
}
auto range_begin() const
{
return std::ranges::begin(parent_->base_);