From 4e49829851e536bd82220872e5ea733221eaf10d Mon Sep 17 00:00:00 2001
From: Niels Lohmann <mail@nlohmann.me>
Date: Sat, 11 Mar 2017 19:26:12 +0100
Subject: [PATCH] :ambulance: fix for #493

Added a test to check if the input stream is good() before executing
getline on it. Also added two test cases that set the failbit and
badbit before calling file_line_buffer.
---
 src/json.hpp                 |  7 +++++++
 src/json.hpp.re2c            |  7 +++++++
 test/src/unit-regression.cpp | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+)

diff --git a/src/json.hpp b/src/json.hpp
index 33456a51..1ed8cca2 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -10988,6 +10988,13 @@ basic_json_parser_74:
                 m_line_buffer.erase(0, num_processed_chars);
                 // read next line from input stream
                 m_line_buffer_tmp.clear();
+
+                // check if stream is still good
+                if (not m_stream->good())
+                {
+                    JSON_THROW(std::invalid_argument("stream error"));
+                }
+
                 std::getline(*m_stream, m_line_buffer_tmp, '\n');
 
                 // add line with newline symbol to the line buffer
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 180f5d3b..c58b29a8 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -10022,6 +10022,13 @@ class basic_json
                 m_line_buffer.erase(0, num_processed_chars);
                 // read next line from input stream
                 m_line_buffer_tmp.clear();
+
+                // check if stream is still good
+                if (not m_stream->good())
+                {
+                    JSON_THROW(std::invalid_argument("stream error"));
+                }
+
                 std::getline(*m_stream, m_line_buffer_tmp, '\n');
 
                 // add line with newline symbol to the line buffer
diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp
index bfd2c954..368c1470 100644
--- a/test/src/unit-regression.cpp
+++ b/test/src/unit-regression.cpp
@@ -28,6 +28,7 @@ SOFTWARE.
 
 #include "catch.hpp"
 
+#define private public
 #include "json.hpp"
 using nlohmann::json;
 
@@ -804,4 +805,35 @@ TEST_CASE("regression tests")
 
         CHECK(j["bool_vector"].dump() == "[false,true,false,false]");
     }
+
+    SECTION("issue #495 - fill_line_buffer incorrectly tests m_stream for eof but not fail or bad bits")
+    {
+        SECTION("setting failbit")
+        {
+            std::stringstream ss;
+            ss << "[1,2,3\n,4,5]";
+
+            json::lexer l(ss);
+
+            CHECK(l.m_line_buffer == "[1,2,3\n");
+
+            l.m_stream->setstate(std::ios_base::failbit);
+
+            CHECK_THROWS_AS(l.fill_line_buffer(), std::invalid_argument);
+        }
+
+        SECTION("setting badbit")
+        {
+            std::stringstream ss;
+            ss << "[1,2,3\n,4,5]";
+
+            json::lexer l(ss);
+
+            CHECK(l.m_line_buffer == "[1,2,3\n");
+
+            l.m_stream->setstate(std::ios_base::badbit);
+
+            CHECK_THROWS_AS(l.fill_line_buffer(), std::invalid_argument);
+        }
+    }
 }