mirror of
https://github.com/nlohmann/json.git
synced 2026-08-04 04:19:03 +00:00
docs: document standards compliance and parse() vs operator>> strictness (#5326)
* docs: document RFC 8259 / JSONTestSuite compliance and parse() vs operator>> strictness The compliance story lived only in tests/src/unit-testsuites.cpp, so drive-by comparisons kept claiming the library "does not fully pass JSONTestSuite". Make it discoverable: - README: add a "Standards compliance" note stating that both nst JSONTestSuite revisions run in CI, that all mandatory y_/n_ cases pass through the strict parse() entry point, and listing the deliberate implementation-defined i_ choices (unbounded nesting, silent BOM stripping, noncharacters forwarded, strict rejection of invalid UTF-8 and lone surrogates, out_of_range.406 on numeric overflow). - features/parsing: add a "Strictness and trailing data" section documenting that parse() is strict and rejects trailing data while operator>> follows relaxed iostream semantics (parses one value and leaves the stream positioned after it) -- the single place a naive test yields a "non-compliant" result. Documentation only; no parser behavior change. Closes #5290. Signed-off-by: manon <youdie006@users.noreply.github.com> * docs: correct test-data vendoring and parse()/operator>> claims per review - README: the JSONTestSuite data is downloaded from nlohmann/json_test_data at configure time, not vendored/committed; say so. - README: only the updated suite runs y_ and n_ cases through strict parse(); the original suite's y_ cases go through operator>>. Narrow the claim. - parsing/index.md and operator_gtgt.md: note that operator>> consumes a number's terminating byte, so concatenated numbers must be whitespace-separated (1 2 works, 1true does not); structural and literal values are unaffected. Signed-off-by: manon <youdie006@users.noreply.github.com> --------- Signed-off-by: manon <youdie006@users.noreply.github.com> Co-authored-by: manon <youdie006@users.noreply.github.com>
This commit is contained in:
@@ -1822,6 +1822,15 @@ The library itself consists of a single header file licensed under the MIT licen
|
||||
|
||||
## Notes
|
||||
|
||||
### Standards compliance
|
||||
|
||||
The library targets strict conformance with [RFC 8259](https://tools.ietf.org/html/rfc8259.html). Both the original [JSONTestSuite](https://github.com/nst/JSONTestSuite) and its updated revision are exercised in CI; their test data is downloaded from [`nlohmann/json_test_data`](https://github.com/nlohmann/json_test_data) at configure time rather than committed to this repository (see [`tests/src/unit-testsuites.cpp`](https://github.com/nlohmann/json/blob/develop/tests/src/unit-testsuites.cpp)):
|
||||
|
||||
- The updated revision runs all mandatory `y_` (must-accept) and `n_` (must-reject) cases through the strict [`parse()`](https://json.nlohmann.me/api/basic_json/parse/) entry point; the original suite runs its `n_` cases through `parse()` and its `y_` cases through [`operator>>`](https://json.nlohmann.me/api/operator_gtgt/).
|
||||
- The `i_` (implementation-defined) cases are, by RFC 8259, free to be accepted *or* rejected, so "passing all `i_` cases" is not a meaningful conformance metric. The library makes deliberate, documented choices there: nesting depth is not artificially limited, a leading UTF-8 byte order mark is silently ignored, [Unicode noncharacters](https://www.unicode.org/faq/private_use.html#nonchar1) are forwarded unchanged, invalid UTF-8 and lone/unpaired UTF-16 surrogates are rejected (stricter than required), and a number that cannot be stored without becoming `NaN`/`INF` raises [`out_of_range.406`](https://json.nlohmann.me/home/exceptions/#jsonexceptionout_of_range406).
|
||||
|
||||
One behavioral nuance is worth calling out, because a superficial test often misreads it as non-compliance: [`parse()`](https://json.nlohmann.me/api/basic_json/parse/) is strict and rejects trailing data after a value, whereas [`operator>>`](https://json.nlohmann.me/api/operator_gtgt/) follows relaxed iostream semantics — it parses a single value and leaves the stream positioned right after it. Feeding "a valid document followed by trailing bytes" through `operator>>` reports success; the same input through `parse()` is rejected. This is a documented two-API design, not a conformance gap. See [**parsing**](https://json.nlohmann.me/features/parsing/) for details.
|
||||
|
||||
### Character encoding
|
||||
|
||||
The library supports **Unicode input** as follows:
|
||||
|
||||
@@ -28,6 +28,22 @@ Inputs consisting of multiple values separated by newlines are handled by the [J
|
||||
By default, the library rejects comments and trailing commas. Both can be enabled with parameters of the `parse`
|
||||
function — see [comments](../comments.md) and [trailing commas](../trailing_commas.md).
|
||||
|
||||
## Strictness and trailing data
|
||||
|
||||
[`parse`](../../api/basic_json/parse.md) reads a single JSON value and requires the whole input to be consumed: any
|
||||
non-whitespace data after the value is reported as a parse error. Use it when you want to guarantee that an input is
|
||||
exactly one complete JSON document.
|
||||
|
||||
[`operator>>`](../../api/operator_gtgt.md) follows relaxed `#!cpp std::istream` semantics instead: it parses one JSON
|
||||
value and leaves the stream positioned right after it, without requiring the rest of the stream to be consumed. This is
|
||||
what makes it possible to read several concatenated values from the same stream, but it also means that "a valid
|
||||
document followed by trailing bytes" is accepted rather than rejected. If you are validating conformance, or need to
|
||||
reject any input that is not exactly one JSON document, prefer `parse`.
|
||||
|
||||
When using `operator>>` to read several concatenated values this way, a value that is a number must be followed by
|
||||
whitespace, because `operator>>` consumes the character that terminates a number — see the
|
||||
[`operator>>` notes](../../api/operator_gtgt.md#notes) for details and examples.
|
||||
|
||||
## SAX vs. DOM parsing
|
||||
|
||||
The library offers two parsing models:
|
||||
|
||||
Reference in New Issue
Block a user