From 358970e3d0fe543dec46733c153d72c7ff20b2e3 Mon Sep 17 00:00:00 2001 From: Luca Date: Thu, 14 Apr 2022 13:00:52 +0200 Subject: [PATCH] fix iterator_input_adapter consuming input before it should --- .../nlohmann/detail/input/input_adapters.hpp | 29 +++++++++++++++---- single_include/nlohmann/json.hpp | 29 +++++++++++++++---- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index d196aec54..49d04395c 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -123,6 +123,7 @@ class input_stream_adapter }; #endif // JSON_NO_IO + // General-purpose iterator-based adapter. It might not be as fast as // theoretically possible for some containers, but it is extremely versatile. template @@ -132,30 +133,46 @@ class iterator_input_adapter using char_type = typename std::iterator_traits::value_type; iterator_input_adapter(IteratorType first, IteratorType last) - : current(std::move(first)), end(std::move(last)) + : current(std::move(first)), end(std::move(last)), current_has_been_consumed(false) {} typename std::char_traits::int_type get_character() { - if (JSON_HEDLEY_LIKELY(current != end)) + + if (JSON_HEDLEY_LIKELY(current_has_been_consumed)) { - auto result = std::char_traits::to_int_type(*current); std::advance(current, 1); - return result; } - return std::char_traits::eof(); + if (JSON_HEDLEY_LIKELY(current != end)) + { + current_has_been_consumed = true; + return std::char_traits::to_int_type(*current); + } + else + { + current_has_been_consumed = false; + return std::char_traits::eof(); + } + } private: IteratorType current; IteratorType end; + bool current_has_been_consumed = false; template friend struct wide_string_input_helper; - bool empty() const + bool empty() { + if (JSON_HEDLEY_LIKELY(current_has_been_consumed)) + { + std::advance(current, 1); + current_has_been_consumed = false; + } + return current == end; } }; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index a29c52997..fdcf4e818 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -5533,6 +5533,7 @@ class input_stream_adapter }; #endif // JSON_NO_IO + // General-purpose iterator-based adapter. It might not be as fast as // theoretically possible for some containers, but it is extremely versatile. template @@ -5542,30 +5543,46 @@ class iterator_input_adapter using char_type = typename std::iterator_traits::value_type; iterator_input_adapter(IteratorType first, IteratorType last) - : current(std::move(first)), end(std::move(last)) + : current(std::move(first)), end(std::move(last)), current_has_been_consumed(false) {} typename std::char_traits::int_type get_character() { - if (JSON_HEDLEY_LIKELY(current != end)) + + if (JSON_HEDLEY_LIKELY(current_has_been_consumed)) { - auto result = std::char_traits::to_int_type(*current); std::advance(current, 1); - return result; } - return std::char_traits::eof(); + if (JSON_HEDLEY_LIKELY(current != end)) + { + current_has_been_consumed = true; + return std::char_traits::to_int_type(*current); + } + else + { + current_has_been_consumed = false; + return std::char_traits::eof(); + } + } private: IteratorType current; IteratorType end; + bool current_has_been_consumed = false; template friend struct wide_string_input_helper; - bool empty() const + bool empty() { + if (JSON_HEDLEY_LIKELY(current_has_been_consumed)) + { + std::advance(current, 1); + current_has_been_consumed = false; + } + return current == end; } };