-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
How to make sure a string or string literal is a valid JSON? #458
Comments
it'd be nice to have a method perhaps a boolean to "validate" json. Similar to how this website works: |
There is a library that just does validation and supports this parser: |
That doesn't do what I need, I asked the author. If I provide a non-valid JSON it'll still hang :/ |
Really, a hang? That's very surprising. Can you share a sample of the json that causes a hang? |
I doubt it's got something to do with the JSON, it's because there is no good way that I know of handling exceptions when programming for a Nintendo 3DS so the program will just freeze. |
JSON for Modern C++ Version 2.1.0 Release date: 2017-01-28 ✨ Exceptions can now be switched off. This can be done by defining the preprocessor symbol JSON_NOEXCEPTION or by passing -fno-exceptions to your compiler. In case the code would usually thrown an exception, abort() is now called. |
Oh, that probably doesn't help much either, as it calls abort. |
So what you really need is for the library to return an error code instead of throwing or aborting when calling |
Yes, pretty much. |
I understand the issue. Inside |
Would it be possible to return an empty json object instead? |
If replacing the throw call is possible, returning a discarded object would be better. You would check it with |
Hey, commenting the JSON_THROW part on except() and unexcept() and then using an "if (json::parse(string) != NULL)" seems to work! |
To properly provide a solution for this issue, I think it would be best to have a dedicated check function that returns a boolean and does not create any |
Yeah, a well-programmed function would be a better idea, but for now this trick works for me. |
I'd definitely add my vote for a validation function. I'm having trouble where the exceptions aren't caught (in a multi-thread app, clang++ on linux) and it's a critical bit of infrastructure. Update: I was able to finally trap exceptions. For anyone else having a similar issue, you may need to use '-stdlib=libc++' along with some other nonsense. |
Such a validation function should be added to 3.0.0. |
Thank you! |
the function has to have a noexcept specifier. |
This is not possible, because then we would need noexpect functions to read from streams. |
? streams don't necessarily throw, actually they don't by default. |
But their functions are not nothrow. |
Even if we don't have It could return a |
the functions are nothrow, but if you can disable/restore the throwing at runtime and in that case noexcept is OK. |
I meant noexcept. I cannot declare a validator function |
Then I misunderstood what was meant by "validation function". Therefore, my comment #458 (comment). |
I shall think of a solution. I do not really like the approach with a pointer though. |
@nlohmann sure it was just an example of the concept. You can pass by reference if you want to. I'm just more a pointer-person. |
@nlohmann but there is one advantage to my proposed pointer concept. It allows you to pass nullptr as an argument which would instruct the parse function to not produce the nlohmann::json object but only validate the string and return either true or false. if you pass by reference then you can't pass a nullptr by reference you know :P |
Example usecase nlohmann::json obj;
if (!nlohmann::parse(json_str, &obj) printf("Invalid json string: %s", json_str.c_str());
if (!nlohmann::parse(json_str, nullptr) printf("Invalid json string: %s", json_str.c_str()); |
The problem is that the current implementation of One way (and I am not convinced it is the best) would be to expose the parser class to the user who then can decide which function to call. This would avoid implementing six versions of all possible parse function. Even better, we may use the same class to cope with MessagePack and CBOR. Hypothetical example: json::parser p(my_input);
json j;
bool x = p.parse(j);
j = p.parse(my_callback); If we add an What do you think? |
Opened #623 as place to discuss the structure of the parsing functions. |
This is what i need! Aha~ #640 |
FYI: It is now possible to call Next thing I would work on is a way to configure |
You can now pass a boolean "allow_exceptions" to the parse functions. If it is false, no exceptions are thrown in case of a parse error. Instead, parsing is stopped at the first error and a JSON value of type "discarded" (check with is_discarded()) is returned.
You can now pass a boolean |
Done. |
Looks like that's correct, given a conversation I had today to test this :) However, the docs indicate that this can't happen:
|
@houglum Is there an issue? |
Just that (I believe) the docs need to be updated. They say that |
Im using Accept method to check if my file is a valid Json or not,
` |
No, but it does read all of the content. You need to reset it to the beginning before you can read from it again. |
Does anyone knows if there is there a performance difference between |
@tawmoto I personally threw out all uses of nlohmann::json from my project because it is bloatware. Not only does it expect you to use exceptions on a regular basis (anti-pattern as the use of exceptions should be an exception itself), but its most fundamental use-case of turning a string into a valid JSON representation can be done in 150 lines of C++ (includes JSON escaping, UTF-8 parsing and does not rely on exceptions). If speed is important to you, I highly suggest not using nlohmann::json. Serialized JSON is such a trivial format that constructing it "manually" makes much more sense than relying on some header-only library. If it is acceptable for you to concatenate strings in order to make up SQL statements, then it should be equally acceptable to do the same for JSON serialization. Only if you need to deserialize JSON you might want to use a library, but then you might as well as consider the amazing Linux tool known as |
@1Hyena Thank you for the answer, speed is important but not mandatory. I have a curl connection which takes 20-30 times more than the parsing, so it's ok. |
@tawmoto |
Accept is not building a DOM representation and is therefore much faster. |
The library offers more than just parsing. If you do not need this, than this library may not be for you.
You can in fact switch off exceptions and still use the library. I would be really interested in seeing the 150 lines of C++ code. |
I would share the code but it's proprietary. The trick is to use lambdas for reporting valid and invalid byte sequences back to the caller. UTF8 validation is 80 lines. JSON escaping is 100 lines. Line width limit is 80 symbols. The The declarations of the said functions are given below. size_t escape_json(
const char *str,
std::function<bool(const char *, size_t)> report_valid,
std::function<bool(const char *, size_t)> report_invalid,
size_t max_symbols, size_t max_bytes
);
size_t parse_utf8(
const char *str,
std::function<bool(const char *, size_t)> report_valid,
std::function<bool(const char *, size_t)> report_invalid,
size_t max_symbols, size_t max_bytes
); |
I'm gonna be sending strings to the parser that might or might not be valid JSONs and I need a way to check they are. I'm programming for a Nintendo 3DS, but using try to catch an exception does not work and the application hangs anyway if it finds an error while parsing. What can I do?
The text was updated successfully, but these errors were encountered: