From 3fd285c014be5ff33ac290e9eb769813751deb63 Mon Sep 17 00:00:00 2001 From: Zach Laine Date: Sun, 1 Dec 2024 20:26:18 -0600 Subject: [PATCH] Correct memory safety issue in converting token iteratos to underlying iterators. See #202. --- include/boost/parser/detail/printing_impl.hpp | 16 +++++----------- include/boost/parser/error_handling.hpp | 12 +++--------- include/boost/parser/lexer.hpp | 12 ++++++++++++ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/boost/parser/detail/printing_impl.hpp b/include/boost/parser/detail/printing_impl.hpp index d46e0af1..daa0a9df 100644 --- a/include/boost/parser/detail/printing_impl.hpp +++ b/include/boost/parser/detail/printing_impl.hpp @@ -1014,10 +1014,8 @@ namespace boost { namespace parser { namespace detail { if (!detail::do_trace(flags_)) return; if constexpr (is_token_iter_v) { - 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:: ~scoped_trace_t() { - if constexpr (is_token_iter_v) { - 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) + impl(first_.range_begin(), first_.base(), first_.range_end()); + else impl(initial_first_, first_, last_); - } } }}} diff --git a/include/boost/parser/error_handling.hpp b/include/boost/parser/error_handling.hpp index 23a4a6cd..8645c02f 100644 --- a/include/boost/parser/error_handling.hpp +++ b/include/boost/parser/error_handling.hpp @@ -192,16 +192,10 @@ namespace boost { namespace parser { template auto normalize_iterators_impl(I first, I it, S last) { - if constexpr (detail::is_token_iter_v) { - 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) + return std::tuple(it.range_begin(), it.base(), it.range_end()); + else return std::tuple(first, it, last); - } } } diff --git a/include/boost/parser/lexer.hpp b/include/boost/parser/lexer.hpp index 42e886f4..44dbef46 100644 --- a/include/boost/parser/lexer.hpp +++ b/include/boost/parser/lexer.hpp @@ -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_);