From 4bb41d065bb0474582042462cf9c34bdbc1e50e3 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 23 Nov 2016 16:57:01 +0100 Subject: [PATCH 1/7] :bug: parsing erroneous files yields an exception (#366) --- src/json.hpp | 6 ++++++ src/json.hpp.re2c | 6 ++++++ test/src/unit-regression.cpp | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/src/json.hpp b/src/json.hpp index e71ffc4a..dbe49c2a 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -7597,6 +7597,12 @@ class basic_json explicit lexer(std::istream& s) : m_stream(&s), m_line_buffer() { + // immediately abort if stream is erroneous + if (s.fail()) + { + throw std::invalid_argument("stream error: " + std::string(strerror(errno))); + } + // fill buffer fill_line_buffer(); diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 9eccc144..ef9910ce 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -7597,6 +7597,12 @@ class basic_json explicit lexer(std::istream& s) : m_stream(&s), m_line_buffer() { + // immediately abort if stream is erroneous + if (s.fail()) + { + throw std::invalid_argument("stream error: " + std::string(strerror(errno))); + } + // fill buffer fill_line_buffer(); diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index 661edc25..ac6d25df 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -495,4 +495,10 @@ TEST_CASE("regression tests") json j = json::parse("22e2222"); CHECK(j == json()); } + + SECTION("issue #366 - json::parse on failed stream gets stuck") + { + std::ifstream f("file_not_found.json"); + CHECK_THROWS_AS(json::parse(f), std::invalid_argument); + } } From dfc49e7afe905fadae756aa24734629a1afdb0fd Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 24 Nov 2016 21:45:10 +0100 Subject: [PATCH 2/7] :bug: fixed a bug if parser was called with a stream at EOF (#367) --- src/json.hpp | 5 ++++- src/json.hpp.re2c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index e71ffc4a..915a60f4 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8743,7 +8743,10 @@ basic_json_parser_66: // append n characters to make sure that there is sufficient // space between m_cursor and m_limit m_line_buffer.append(1, '\x00'); - m_line_buffer.append(n - 1, '\x01'); + if (n > 0) + { + m_line_buffer.append(n - 1, '\x01'); + } } else { diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 9eccc144..9b21c828 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -7892,7 +7892,10 @@ class basic_json // append n characters to make sure that there is sufficient // space between m_cursor and m_limit m_line_buffer.append(1, '\x00'); - m_line_buffer.append(n - 1, '\x01'); + if (n > 0) + { + m_line_buffer.append(n - 1, '\x01'); + } } else { From 8014637ad1a05914fc069213c1f5c93aa9e2da17 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 24 Nov 2016 21:53:41 +0100 Subject: [PATCH 3/7] :white_check_mark: added a test for EOF error (#367) --- test/src/unit-regression.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index 661edc25..414ee71c 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -495,4 +495,19 @@ TEST_CASE("regression tests") json j = json::parse("22e2222"); CHECK(j == json()); } + + SECTION("issue #367 - calling stream at EOF") + { + std::stringstream ss; + json j; + ss << "123"; + CHECK_NOTHROW(j << ss); + + // see https://github.com/nlohmann/json/issues/367#issuecomment-262841893: + // ss is not at EOF; this yielded an error before the fix + // (threw basic_string::append). No, it should just throw + // a parse error because of the EOF. + CHECK_THROWS_AS(j << ss, std::invalid_argument); + CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input"); + } } From 1407bbf94cd3a6b927f3e52a946b82eddbf3ff3c Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 24 Nov 2016 21:54:05 +0100 Subject: [PATCH 4/7] :lipstick: fixed indentation --- benchmarks/benchmarks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/benchmarks.cpp b/benchmarks/benchmarks.cpp index efb26cf2..745123c9 100644 --- a/benchmarks/benchmarks.cpp +++ b/benchmarks/benchmarks.cpp @@ -58,7 +58,7 @@ static void bench(benchpress::context& ctx, for (size_t i = 0; i < ctx.num_iterations(); ++i) { - // clear flags and rewind + // clear flags and rewind istr.clear(); istr.seekg(0); json j; From 472d0045ba41fd22412c7b697e804c248ce109bf Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 24 Nov 2016 21:56:21 +0100 Subject: [PATCH 5/7] :memo: updating README after fixing #299 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5e899ac2..eca178af 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Build Status](https://travis-ci.org/nlohmann/json.svg?branch=master)](https://travis-ci.org/nlohmann/json) [![Build Status](https://ci.appveyor.com/api/projects/status/1acb366xfyg3qybk/branch/develop?svg=true)](https://ci.appveyor.com/project/nlohmann/json) [![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json) [![Try online](https://img.shields.io/badge/try-online-blue.svg)](http://melpon.org/wandbox/permlink/fsf5FqYe6GoX68W6) [![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT) @@ -501,6 +502,7 @@ I deeply appreciate the help of the following people. - [Denis Andrejew](https://github.com/seeekr) fixed a grammar issue in the README file. - [Pierre-Antoine Lacaze](https://github.com/palacaze) found a subtle bug in the `dump()` function. - [TurpentineDistillery](https://github.com/TurpentineDistillery) pointed to [`std::locale::classic()`](http://en.cppreference.com/w/cpp/locale/locale/classic) to avoid too much locale joggling. +- [cgzones](https://github.com/cgzones) had an idea how to fix the Coverity scan. Thanks a lot for helping out! From c39c36e6adad209db38682f5ebb26096d47d421b Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 24 Nov 2016 22:05:29 +0100 Subject: [PATCH 6/7] :lipstick: fixed indentation --- test/src/unit-regression.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index 414ee71c..cda578ab 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -495,19 +495,19 @@ TEST_CASE("regression tests") json j = json::parse("22e2222"); CHECK(j == json()); } - - SECTION("issue #367 - calling stream at EOF") - { - std::stringstream ss; - json j; - ss << "123"; - CHECK_NOTHROW(j << ss); - // see https://github.com/nlohmann/json/issues/367#issuecomment-262841893: - // ss is not at EOF; this yielded an error before the fix - // (threw basic_string::append). No, it should just throw - // a parse error because of the EOF. - CHECK_THROWS_AS(j << ss, std::invalid_argument); - CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input"); - } + SECTION("issue #367 - calling stream at EOF") + { + std::stringstream ss; + json j; + ss << "123"; + CHECK_NOTHROW(j << ss); + + // see https://github.com/nlohmann/json/issues/367#issuecomment-262841893: + // ss is not at EOF; this yielded an error before the fix + // (threw basic_string::append). No, it should just throw + // a parse error because of the EOF. + CHECK_THROWS_AS(j << ss, std::invalid_argument); + CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input"); + } } From f194db9aa684b494678ab9cb08c659f732af7fc6 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 24 Nov 2016 22:07:35 +0100 Subject: [PATCH 7/7] :white_check_mark: added assertion for warning from #368 --- src/json.hpp | 1 + src/json.hpp.re2c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/json.hpp b/src/json.hpp index 915a60f4..81dc5f8f 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8736,6 +8736,7 @@ basic_json_parser_66: m_line_buffer.clear(); for (m_cursor = m_start; m_cursor != m_limit; ++m_cursor) { + assert(m_cursor != nullptr); m_line_buffer.append(1, static_cast(*m_cursor)); } } diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 9b21c828..3b2c7500 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -7885,6 +7885,7 @@ class basic_json m_line_buffer.clear(); for (m_cursor = m_start; m_cursor != m_limit; ++m_cursor) { + assert(m_cursor != nullptr); m_line_buffer.append(1, static_cast(*m_cursor)); } }