Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fill_line_buffer incorrectly tests m_stream for eof but not fail or bad bits #493

Closed
TestMonkey9000 opened this issue Mar 9, 2017 · 7 comments

Comments

@TestMonkey9000
Copy link

If the json object is asked to parse from a stream, the stream must be valid otherwise the json object goes into an infinite loop. The current code only tests for the end of file condition which assumes the incoming stream does not have the bad or fail bits set. I think a more general approach is to test with good() rather than eof().

            // no stream is used or end of file is reached
            if (m_stream == nullptr or m_stream->eof())

Should be:

            // no stream is used or end of file is reached
            if (m_stream == nullptr or !m_stream->good())

This will throw an exception if the stream is not open or has another issue rather than loop.
Test code:

#include "json.hpp"
using json = nlohmann::json;

#include <fstream>

int main(int argc, char** argv)
{

   std::ifstream istr("non_existant_file");
   json j = json::parse(istr);
   return 0;
}
@nlohmann
Copy link
Owner

nlohmann commented Mar 9, 2017

Which version did you try? This should be fixed in the last version.

@TestMonkey9000
Copy link
Author

Clearly an old version - ended up being v2.0.5. It is fixed in the constructor on the version I just pulled - v2.1.1. Is there an issue if the stream throws fail/bad while reading the stream? For example, std::getline() can set the fail bit when it can't store an the entire buffer up to the delimiter ('\n') or it can't extract any characters from the stream - both highly unlikely scenarios but throwing it out there as a potential strange behavior which would cause an infinite loop.

@nlohmann
Copy link
Owner

You're right - we do not check the stream once we started parsing. I shall have a look whether I can create a test case for this.

@nlohmann nlohmann self-assigned this Mar 10, 2017
@nlohmann nlohmann added this to the Release 3.0.0 milestone Mar 10, 2017
@nlohmann
Copy link
Owner

nlohmann commented Mar 10, 2017

I need a test case where this is an issue.

nlohmann added a commit that referenced this issue Mar 11, 2017
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.
@nlohmann
Copy link
Owner

@TestMonkey9000 With commit 4e49829 I added a check to make sure the stream is OK before calling std::getline on it. Could you have a look at it?

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Mar 11, 2017
@TestMonkey9000
Copy link
Author

The solution looks fine - curious why use good() and not fail()? Asking because good() checks eofbit, failbit, and badbit and eofbit is checked as the other side of the overall conditional. It seemed like since it was checked above, you would either change that check to "not good()" or the inserted check to "not fail()". From a functionality standpoint, I don't see why it would matter because there isn't an operation on the stream operation between the two points...just being pedantic.

nlohmann added a commit that referenced this issue Mar 14, 2017
Also merged develop into this feature branch.
nlohmann added a commit that referenced this issue Mar 14, 2017
Replaced old std::invalid_argument exception by parse_error.111 to have
unified exceptions in case of input stream errors.
@nlohmann
Copy link
Owner

That's a good point. I overworked this.

@nlohmann nlohmann removed the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Mar 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants