Skip to content

Commit

Permalink
Set eofbit on exhausted input stream.
Browse files Browse the repository at this point in the history
	Fix issue nlohmann#1340.

        The eofbit is set manually since we don't go through the
	stream interface. We could maybe use the stream interface
	instead, but there are some assumptions regarding which
	exception go through, so this seems to be the most prudent
	approach for now.
  • Loading branch information
mefyl committed Nov 7, 2018
1 parent d2e6e1b commit 4e5b62b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
12 changes: 9 additions & 3 deletions include/nlohmann/detail/input/input_adapters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -79,7 +79,13 @@ class input_stream_adapter : public input_adapter_protocol
// end up as the same value, eg. 0xFFFFFFFF.
std::char_traits<char>::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:
Expand Down
10 changes: 7 additions & 3 deletions single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -2128,7 +2128,11 @@ class input_stream_adapter : public input_adapter_protocol
// end up as the same value, eg. 0xFFFFFFFF.
std::char_traits<char>::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:
Expand Down
12 changes: 12 additions & 0 deletions test/src/unit-regression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1708,3 +1708,15 @@ 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;
CHECK_THROWS_AS(s >> j, json::parse_error const&);
CHECK(s.eof());
}
}

0 comments on commit 4e5b62b

Please sign in to comment.