diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index 79a19c17..e11fb896 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -60,8 +60,8 @@ class input_stream_adapter : public input_adapter_protocol ~input_stream_adapter() override { // clear stream flags; we use underlying streambuf I/O, do not - // maintain ifstream flags - is.clear(); + // maintain ifstream flags, except eof + is.clear(is.rdstate() & std::ios::eofbit); } explicit input_stream_adapter(std::istream& i) @@ -79,7 +79,11 @@ class input_stream_adapter : public input_adapter_protocol // end up as the same value, eg. 0xFFFFFFFF. std::char_traits::int_type get_character() override { - return sb.sbumpc(); + auto res = sb.sbumpc(); + // set eof manually, as we don't use the istream interface. + if (res == EOF) + is.clear(is.rdstate() | std::ios::eofbit); + return res; } private: diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 931e7b36..873e75d5 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -2109,8 +2109,8 @@ class input_stream_adapter : public input_adapter_protocol ~input_stream_adapter() override { // clear stream flags; we use underlying streambuf I/O, do not - // maintain ifstream flags - is.clear(); + // maintain ifstream flags, except eof + is.clear(is.rdstate() & std::ios::eofbit); } explicit input_stream_adapter(std::istream& i) @@ -2128,7 +2128,11 @@ class input_stream_adapter : public input_adapter_protocol // end up as the same value, eg. 0xFFFFFFFF. std::char_traits::int_type get_character() override { - return sb.sbumpc(); + auto res = sb.sbumpc(); + // set eof manually, as we don't use the istream interface. + if (res == EOF) + is.clear(is.rdstate() | std::ios::eofbit); + return res; } private: diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index 5f007980..058c71c0 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -1708,3 +1708,16 @@ TEST_CASE("regression tests") CHECK(expected == data); } } + +TEST_CASE("regression tests, exceptions dependent", "[!throws]") +{ + SECTION("issue #1340 - eof not set on exhausted input stream") + { + std::stringstream s("{}{}"); + json j; + s >> j; + s >> j; + CHECK_THROWS_AS(s >> j, json::parse_error const&); + CHECK(s.eof()); + } +}