From ae59fbb5a4bad534819359ae6b76f413f804dab0 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Fri, 23 Oct 2026 10:27:08 +0200 Subject: [PATCH] 2.3.8: finish_input helper for the strict-EOF block in the parser (#5891) sax_parse keeps its if (result) guard and return value. Also adds the clang-tidy NOLINT for the 2.3.6 message table. Signed-off-by: Niels Lohmann --- include/nlohmann/detail/input/lexer.hpp | 2 +- include/nlohmann/detail/input/parser.hpp | 63 +++++++++++++----------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/include/nlohmann/detail/input/lexer.hpp b/include/nlohmann/detail/input/lexer.hpp index 3b9d409bf..ab504c8d6 100644 --- a/include/nlohmann/detail/input/lexer.hpp +++ b/include/nlohmann/detail/input/lexer.hpp @@ -688,7 +688,7 @@ class lexer : public lexer_base case 0x1E: case 0x1F: { - static const char* const control_character_messages[32] = + static const char* const control_character_messages[32] = // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) { "invalid string: control character U+0000 (NUL) must be escaped to \\u0000", "invalid string: control character U+0001 (SOH) must be escaped to \\u0001", diff --git a/include/nlohmann/detail/input/parser.hpp b/include/nlohmann/detail/input/parser.hpp index b2fc7548c..f06488c99 100644 --- a/include/nlohmann/detail/input/parser.hpp +++ b/include/nlohmann/detail/input/parser.hpp @@ -165,20 +165,7 @@ class parser if (result) { - if (strict) - { - // strict mode: next byte must be EOF - if (get_token() != token_type::end_of_input) - { - return syntax_error(*sax, exception_message(token_type::end_of_input, "value")); - } - } - else - { - // the caller keeps using the input: position it right after - // the value by leaving the character that terminated it - m_lexer.release_lookahead(); - } + return finish_input(*sax, strict); } return result; @@ -202,6 +189,39 @@ class parser return m_lexer.get_string(); } + /*! + @brief apply the end-of-input handling after a value was parsed + + In strict mode, the next token must be the end of the input; otherwise + parse_error.101 is reported through @a sax. In non-strict mode, the + lookahead is released so the caller can keep reading the input right after + the parsed value. + + @param[in,out] sax the SAX parser to report an error to + @param[in] strict whether to expect the last token to be EOF + @return true, or what @a sax returned for the error + */ + template + bool finish_input(SAX& sax, const bool strict) + { + if (strict) + { + // strict mode: next byte must be EOF + if (get_token() != token_type::end_of_input) + { + return syntax_error(sax, exception_message(token_type::end_of_input, "value")); + } + } + else + { + // the caller keeps using the input: position it right after + // the value by leaving the character that terminated it + m_lexer.release_lookahead(); + } + + return true; + } + /*! @brief run a DOM SAX parser to completion and position the lexer @@ -221,20 +241,7 @@ class parser { sax_parse_internal(&sdp); - if (strict) - { - // in strict mode, input must be completely read - if (get_token() != token_type::end_of_input) - { - syntax_error(sdp, exception_message(token_type::end_of_input, "value")); - } - } - else - { - // the caller keeps using the input: position it right after - // the value by leaving the character that terminated it - m_lexer.release_lookahead(); - } + static_cast(finish_input(sdp, strict)); return !sdp.is_errored(); }