diff --git a/src/json.hpp b/src/json.hpp
index 9a201153..fad9d87a 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -8826,8 +8826,10 @@ class basic_json
         {
             // clear stream flags
             is.clear();
-            // set stream after last processed char
-            is.seekg(start_position + static_cast<std::streamoff>(processed_chars - 1));
+            // We initially read a lot of characters into the buffer, and we
+            // may not have processed all of them. Therefore, we need to
+            // "rewind" the stream after the last processed char.
+            is.seekg(start_position + static_cast<std::streamoff>(processed_chars));
         }
 
         int get_character() override
@@ -8840,20 +8842,19 @@ class basic_json
                 // store number of bytes in the buffer
                 fill_size = static_cast<size_t>(is.gcount());
 
+                // the buffer is ready
+                buffer_pos = 0;
+
                 // remember that filling did not yield new input
                 if (fill_size == 0)
                 {
                     eof = true;
+                    return std::char_traits<char>::eof();
                 }
-
-                // the buffer is ready
-                buffer_pos = 0;
             }
 
             ++processed_chars;
-            return eof
-                   ? std::char_traits<char>::eof()
-                   : buffer[buffer_pos++] & 0xFF;
+            return buffer[buffer_pos++] & 0xFF;;
         }
 
         std::string read(size_t offset, size_t length) override
diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp
index 1ff8f987..db281ac4 100644
--- a/test/src/unit-regression.cpp
+++ b/test/src/unit-regression.cpp
@@ -599,6 +599,118 @@ TEST_CASE("regression tests")
                           "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected end of input");
     }
 
+    SECTION("issue #367 - behavior of operator>> should more closely resemble that of built-in overloads")
+    {
+        SECTION("(empty)")
+        {
+            std::stringstream ss;
+            json j;
+            CHECK_THROWS_AS(ss >> j, json::parse_error);
+            CHECK_THROWS_WITH(ss >> j,
+                              "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected end of input");
+        }
+
+        SECTION("(whitespace)")
+        {
+            std::stringstream ss;
+            ss << "   ";
+            json j;
+            CHECK_THROWS_AS(ss >> j, json::parse_error);
+            CHECK_THROWS_WITH(ss >> j,
+                              "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected end of input");
+        }
+
+        SECTION("one value")
+        {
+            std::stringstream ss;
+            ss << "111";
+            json j;
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == 111);
+
+            CHECK_THROWS_AS(ss >> j, json::parse_error);
+            CHECK_THROWS_WITH(ss >> j,
+                              "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected end of input");
+        }
+
+        SECTION("one value + whitespace")
+        {
+            std::stringstream ss;
+            ss << "222 \t\n";
+            json j;
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == 222);
+
+            CHECK_THROWS_AS(ss >> j, json::parse_error);
+            CHECK_THROWS_WITH(ss >> j,
+                              "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected end of input");
+        }
+
+        SECTION("whitespace + one value")
+        {
+            std::stringstream ss;
+            ss << "\n\t 333";
+            json j;
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == 333);
+
+            CHECK_THROWS_AS(ss >> j, json::parse_error);
+            CHECK_THROWS_WITH(ss >> j,
+                              "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected end of input");
+        }
+
+        SECTION("three values")
+        {
+            std::stringstream ss;
+            ss << " 111 \n222\n \n  333";
+            json j;
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == 111);
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == 222);
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == 333);
+
+            CHECK_THROWS_AS(ss >> j, json::parse_error);
+            CHECK_THROWS_WITH(ss >> j,
+                              "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected end of input");
+        }
+
+        SECTION("literals without whitespace")
+        {
+            std::stringstream ss;
+            ss << "truefalsenull\"\"";
+            json j;
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == true);
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == false);
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == nullptr);
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == "");
+
+            CHECK_THROWS_AS(ss >> j, json::parse_error);
+            CHECK_THROWS_WITH(ss >> j,
+                              "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected end of input");
+        }
+
+        SECTION("example from #529")
+        {
+            std::stringstream ss;
+            ss << "{\n    \"one\"   : 1,\n    \"two\"   : 2\n}\n{\n    \"three\" : 3\n}";
+            json j;
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == json({{"one", 1}, {"two", 2}}));
+            CHECK_NOTHROW(ss >> j);
+            CHECK(j == json({{"three", 3}}));
+
+            CHECK_THROWS_AS(ss >> j, json::parse_error);
+            CHECK_THROWS_WITH(ss >> j,
+                              "[json.exception.parse_error.101] parse error at 1: syntax error - unexpected end of input");
+        }
+    }
+
     SECTION("issue #389 - Integer-overflow (OSS-Fuzz issue 267)")
     {
         // original test case