Skip to content

Commit

Permalink
basic_parser_impl: make sentinel() return a unique pointer
Browse files Browse the repository at this point in the history
Right now, sentinel() casts the `basic_parser_impl` pointer (`this`)
to `const char *`, but that pointer is not unique if the input buffer
happens to be placed right before the `basic_parser_impl` instance -
the end of that buffer then has the same address as
`basic_parser_impl`.

Example code:

  struct {
    char buffer[8]{"{\"12345\""};
    boost::json::stream_parser p;
  } s;
  s.p.write(s.buffer, sizeof(s.buffer));
  s.p.write(":0}", 3);

This stops parsing at the end of the buffer, and then the
`incomplete()` check in `parse_string()` will return true; the second
`write()` call will crash with assertion failure:

  boost/json/basic_parser_impl.hpp:1016: const char* boost::json::basic_parser<Handler>::parse_unescaped(const char*, std::integral_constant<bool, StackEmpty_>, std::integral_constant<bool, AllowComments_>, bool) [with bool StackEmpty_ = true; bool IsKey_ = true; Handler = boost::json::detail::handler]: Assertion `*cs == '\x22'' failed.

This change introduces changes `sentinel()` to return the address of a
static variable instead, which is guaranteed to be unique.
  • Loading branch information
MaxKellermann committed Nov 21, 2022
1 parent 893df14 commit 9562730
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions include/boost/json/basic_parser_impl.hpp
Expand Up @@ -217,8 +217,8 @@ const char*
basic_parser<Handler>::
sentinel()
{
return reinterpret_cast<
const char*>(this);
static const char sentinel{};
return &sentinel;
}

template<class Handler>
Expand Down

0 comments on commit 9562730

Please sign in to comment.