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

Parse error #1761

Closed
xabik opened this issue Sep 21, 2019 · 13 comments
Closed

Parse error #1761

xabik opened this issue Sep 21, 2019 · 13 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@xabik
Copy link

xabik commented Sep 21, 2019

When I execute this function, I get an exception like
nlohmann :: detail :: parse_error

	void load_info(std::vector<json> info) {
		std::ifstream f;
		f.open("info.json", std::ifstream::in);
		json building;
		while (f >> building) {
			info.push_back(building);
		}
		f.close();
	}

file info.json with info like this

{"coordinates":{"lt":{"x":52,"y":121},"rb":{"x":140,"y":43}},"order":1,"type":19}
{"coordinates":{"lt":{"x":55,"y":118},"rb":{"x":137,"y":46}},"order":3,"type":19}
{"coordinates":{"lt":{"x":54,"y":120},"rb":{"x":135,"y":43}},"order":2,"type":21}
{"coordinates":{"lt":{"x":54,"y":123},"rb":{"x":135,"y":40}},"order":4,"type":21}

but if i change my function to:

	void load_info(std::vector<json> info) {
		std::ifstream f;
		f.open("info.json", std::ifstream::in);
		json building;
		for (int i = 0; i < 4; i++) {
			f >> building;
			info.push_back(building);
		}
		f.close();
	}

function work good. How i can fix this?

MS Visual Studio 2017. Windows 7.

Version library 3.7.0 Release

@nlohmann
Copy link
Owner

What is the exact exception description?

@xabik
Copy link
Author

xabik commented Sep 21, 2019

Message with exception have only address in memory. Debugger stop program in case 4: in

    bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
                     const detail::exception& ex)
    {
        errored = true;
        if (allow_exceptions)
        {
            // determine the proper exception type from the id
            switch ((ex.id / 100) % 100)
            {
                case 1:
                    JSON_THROW(*static_cast<const detail::parse_error*>(&ex));
                case 4:
                    JSON_THROW(*static_cast<const detail::out_of_range*>(&ex));
                // LCOV_EXCL_START
                case 2:
                    JSON_THROW(*static_cast<const detail::invalid_iterator*>(&ex));
                case 3:
                    JSON_THROW(*static_cast<const detail::type_error*>(&ex));
                case 5:
                    JSON_THROW(*static_cast<const detail::other_error*>(&ex));
                default:
                    assert(false);
                    // LCOV_EXCL_STOP
            }
        }
        return false;
    }

@xabik xabik changed the title Parse errror Parse error Sep 21, 2019
@nlohmann
Copy link
Owner

You should still be able to access the what() member of the exception. As it seems to be an json::exception::out_of_range which only occurs in https://github.com/nlohmann/json/blob/develop/include/nlohmann/detail/input/parser.hpp#L265, your input seems to contain number that overflow. This is strange.

  • Can you narrow down the error to a smaller input that you can share?
  • Can you try to access the exception's what() message as it should give you the token where the error happend?

@xabik
Copy link
Author

xabik commented Sep 23, 2019

For more detail, I wrote a simple program. It first writes the information to a file, and then reads it. An error occurs at the reading stage.

#include "pch.h"
#include <iostream>
#include <nlohmann/json.hpp>
#include <fstream>

using json = nlohmann::json;

void write_to_file(json info) {
	std::ofstream f;
	f.open("info.json", std::ofstream::app);
	f << info << std::endl;
	f.close();
}

void read_from_file(std::vector<json> info) {
	std::ifstream f;
	f.open("info.json", std::ifstream::in);
	json building;
	while (f >> building) {
		info.push_back(building);
	}
	f.close();
}

int main()
{
	json test1 = {
	  {"type", 19},
	  {"coordinates", {
		{"lt", {
		  {"x", 52},
		  {"y", 121}
		}},
		{"rb", {
		  {"x", 140},
		  {"y", 43}
		}}
	  }},
	  {"order", 1}
	};

	json test2 = {
	  {"type", 21},
	  {"coordinates", {
		{"lt", {
		  {"x", 55},
		  {"y", 118}
		}},
		{"rb", {
		  {"x", 137},
		  {"y", 46}
		}}
	  }},
	  {"order", 3}
	};
	write_to_file(test1);
	write_to_file(test2);
	std::vector<json> info;
	read_from_file(info);
}

The what() member of the exception = {_What=0x009e0240 "[json.exception.parse_error.101] parse error at line 2, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal" ...} | __std_exception_data

In https://nlohmann.github.io/json/classnlohmann_1_1basic__json_af1efc2468e6022be6e35fc2944cabe4d.html Error 101 describes is an invalid format. But the file is written using the library functions. Perhaps I am writing incorrectly?

@xabik
Copy link
Author

xabik commented Sep 23, 2019

locals

@nlohmann
Copy link
Owner

I can reproduce the exception. I'll try to dig deeper later this week.

@DJLink
Copy link

DJLink commented Sep 30, 2019

I'm running into a similar exception as @xabik mentioned. Weirdly if I have my json in "beautified" mode when loading it parses correctly, using any online tool to minify (or writing it by hand) and the same exact json hits that exception.

So I decided to break that minified json into a 2 line and now it loads.
1 line minified json gives exceptions, >1 loads ok.
Hope this helps.

@xabik
Copy link
Author

xabik commented Oct 4, 2019

@DJLink, can you attach file with json which loads correctly? I try to repeat loading.

@DJLink
Copy link

DJLink commented Oct 5, 2019

Here are 3 files, the single line file fails, the other load ok.

I'm using nlohmann::json::parse()

test_ok_2_lines.txt
test_ok_beautify.txt
test_fail.txt

@stale
Copy link

stale bot commented Nov 4, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Nov 4, 2019
@nlohmann nlohmann removed the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Nov 5, 2019
@nlohmann

This comment has been minimized.

@nlohmann
Copy link
Owner

nlohmann commented Nov 5, 2019

I had another look at #1761 (comment). The issue is that operator>> does not return false in case of a parse error. Hence, for an input like

{"coordinates":{"lt":{"x":52,"y":121},"rb":{"x":140,"y":43}},"order":1,"type":19}
{"coordinates":{"lt":{"x":55,"y":118},"rb":{"x":137,"y":46}},"order":3,"type":21}

operator>> only returns successfully twice - calling it a third time yields a parse error exception.

Hence, you would need code like

    try {
        while (f >> building) {
            info.push_back(building);
        }
    } catch (json::exception&)
    {}

to parse an arbitrary number of JSON values in a file.

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Nov 5, 2019
@nlohmann
Copy link
Owner

Do you need further assistance with this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

3 participants