nlohmann / json

JSON for Modern C++
https://json.nlohmann.me
MIT License
42.57k stars 6.69k forks source link

Intermittent issues with loadJSON #1484

Closed Stryxic closed 5 years ago

Stryxic commented 5 years ago

I've had a C++ program that's been able to save and load JSON files fine in the past, however recently it's giving a json.exception.parse_error.101, unexpected end of input.

The code which is causing the error is very simple, just

loadJSON("test.json");

Where test.json is stored in the same directory as the program running it. I've also attempted with the absolute path, both return the same error.

I would expect it to load the JSON as expected. Using std::ifstream ifs("test.json"); json j = json::parse(ifs);

also returns the same error, and just for the hell I tried

std::ifstream my_file("test.json"); json j; j << my_file;

as well. The JSON file is good, it's the first one on JSON.org and I double checked with another parser.

My system is Windows 7, I'm compiling with MinGW version w64.0, with CMake version 3.10.3 on CLion. I'm using the released version rather than the develop branch.

Any help would be appreciated as I'm really not too sure what has caused this out of the blue - I hadn't changed the code which was loading JSON files, yet it broke anyways. If you've any suggestions on how I can clear up my issue to make it easier to solve, I'd be grateful.

nickaein commented 5 years ago

Are you sure whether file encoding format is OK (e.g. UTF-8 or ASCII) and the file is not truncated?

Also, inspecting the exception message could be helpful. Wrap the json::parse call inside a try/catch block similar to this: https://nlohmann.github.io/json/classnlohmann_1_1basic__json_af1efc2468e6022be6e35fc2944cabe4d.html

Stryxic commented 5 years ago

Pretty sure that the encoding is fine - These files have been good for me previously, including the example I tried. Just to be sure I saved it as a couple of different encodings to try, and I'm not sure if it'd be truncation due to the error I received after putting it in the try/catch block -

message: [json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal exception id: 101 byte position of error: 1

With the entire contents of the JSON being from the example site, which I've included just to save a click -

{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } }

nickaein commented 5 years ago

I tested this JSON and cannot reproduce this error.

Having error at first byte (byte position of error: 1) indicates that the file probably cannot be opened in the first place. Make sure it is indeed opened without error before parsing:

std::ifstream fin("input.txt");

if (!fin)
{
    cout << "cannot open file" << endl;
    return;
}

If that was not the problem, make sure the file stream is at beginning by checking its current position (should be 0):

cout << "Current pos: " << fin.tellg() << endl;

Ultimately, you should open the file with a hex editor to make sure there is no extra unexpected hidden bytes at the beginning (e.g. BOM but JSON library could probably handle BOM for UTF8).

Stryxic commented 5 years ago

I've confirmed that the file is indeed starting at position 0, and that the file is valid.

I've also checked with a hex editor and found no unexpected hidden additional bytes at the beginning. Just to double check, these are the first 16 bytes as show by HxD - 7B 22 67 6C 6F 73 73 61 72 79 22 3A 20 7B 0D 0A corresponding to {"glossary": {.. in the json.

Just to double check that no changes had been made to any file, I checked the differences between my included nhlohmann directory and a fresh download, the only difference being in json.hpp with result["platform"] = "events.json"; on line 340. I'm not sure why it's this way, as I'm on Windows rather than Mac, so it shouldn't make any difference surely.

nickaein commented 5 years ago

The latest stable release is 3.5.0 which you can download from releases page. Nevertheless, older releases shouldn't have any problem in parsing this file.

I'm still skeptic if the file can be read correctly since the parser is throwing exception at the very first byte. You might want to try these to dig the issue:

  1. Try to parse a hard-coded JSON inside source file:
std::string json_data = R"my_json({
"glossary": {
    "title": "example glossary",
    "GlossDiv": {
        "title": "S",
        "GlossList": {
            "GlossEntry": {
                "ID": "SGML",
                "SortAs": "SGML",
                "GlossTerm": "Standard Generalized Markup Language",
                "Acronym": "SGML",
                "Abbrev": "ISO 8879:1986",
                "GlossDef": {
                    "para": "A meta-markup language, used to create markup languages such as DocBook.",
                    "GlossSeeAlso": ["GML", "XML"]
                },
                "GlossSee": "markup"
            }
        }
    }
}
})my_json";

json::parse(json_data);
  1. Instead of parsing the JSON, just read whole input file contents and write it to another file. Check the content of newly written file. If there is any issue in the written file, that is a red flag.
  2. Put some white-spaces at the beginning of file. If the parser is actually processing file contents, the byte value of thrown exception should increase and indicate the number of whites-paces since the parser skips over prefix whites-paces. If after padding the byte value is still zero, it shows that parser cannot read even a single byte from file.
Stryxic commented 5 years ago
  1. The hard-coded JSON file worked
  2. Reading and then writing the files separately both worked without issue
  3. Adding whitespace to the JSON file still failed at byte 0

It would seem that it's failing to load the file for some reason, but whatever that reason is evades me.

nlohmann commented 5 years ago

Any idea how to proceed here?