From 9562730b0fca0e4efb027b151892d2938a0d7b3f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 21 Nov 2022 14:53:00 +0100 Subject: [PATCH] basic_parser_impl: make sentinel() return a unique pointer 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::parse_unescaped(const char*, std::integral_constant, std::integral_constant, 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. --- include/boost/json/basic_parser_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/json/basic_parser_impl.hpp b/include/boost/json/basic_parser_impl.hpp index 7ab6f1355..e95af215a 100644 --- a/include/boost/json/basic_parser_impl.hpp +++ b/include/boost/json/basic_parser_impl.hpp @@ -217,8 +217,8 @@ const char* basic_parser:: sentinel() { - return reinterpret_cast< - const char*>(this); + static const char sentinel{}; + return &sentinel; } template