Commit Graph
15 Commits
Author SHA1 Message Date
Niels Lohmann ccc005c012 Fix contradictions between the documentation, the README, and the library (#5825)
- Discarded values: the legacy macro only changes <= and >=; != is true by default
- Out-of-range numbers are rejected while parsing, not stored as NaN
- merge_diff round trip: point to the ordered_json caveat
- ensure_ascii example shows the escaped output
- out_of_range.405 is thrown for "remove"/"move" on the root, not "add"
- CBOR stores binary subtypes as tags
- Integer/float comparison uses exact values, not conversion
- diff, flatten, and the binary writers are depth-bounded
- FAQ: max_digits10 for serialization, trailing commas are supported
- out_of_range.407 is still thrown by to_bon8
- FetchContent_MakeAvailable needs CMake 3.14
- json_fwd.hpp contents, operator< link, RFC 7396 for merge patch
- README: dump() wording, merge_diff, MSYS2/build2, patch comment typos,
  operator[] link, embedded CMake example aligned with the docs

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-14 17:40:55 +02:00
Niels Lohmann 3c465beb61 Add tests for error_handler_t::keep in dump() (#4555)
Squashed onto develop from:
- Add error_handler_t::keep to copy invalid UTF-8 bytes unchanged
- Mention error_handler_t::keep in the README

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-07 19:17:57 +02:00
Niels Lohmann 78ddd95794 Document GCC < 11 incomplete-type error with optional members (#3669) (#5596)
* Document GCC < 11 incomplete-type error with optional members (#3669)

With GCC 10 and older in C++11/14 mode, a free to_json() for a type
holding an optional<Dummy> (Dummy constructible from json) fails with
"invalid use of incomplete type detector<...to_json_function...>".
ADL for Dummy finds the unrelated to_json and closes an instantiation
cycle through optional's converting constructor. The same error
reproduces without the library, so it can't be fixed here.

Add a FAQ entry explaining the cause and the hidden-friend workaround,
recommend hidden friends in the arbitrary types docs, and add a
regression test that keeps the workaround compiling on GCC 7-10.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Use the #3669 fixture's optional member in to_json

Issue3669Holder::d is never read, so clang's -Weverything -Werror build
(ci_test_clang) fails with -Wunused-private-field. Reference the member
in the hidden-friend to_json; this does not affect the instantiation
cycle the fixture reproduces.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-04 11:46:13 +02:00
Niels Lohmann 63c10a51fc Review and extend the documentation, and check it in CI (#5638)
* Review and extend the documentation, and check it in CI

A review of all documentation pages found factual errors, dead links,
missing cross-references, and gaps in examples. This fixes them and adds
checks so the same problems are caught automatically.

Fixes:
- wrong signatures and version histories (operator!= C++20 member,
  binary() subtype type, get<PointerType>(), JSON_NO_THREAD_LOCAL, ...)
- stale descriptions (number parsing since #5283, UBJSON table, SAX
  example that no longer compiled, tsl::ordered_map advice)
- dead internal and external links; repology.org badges (the domain is
  suspended) replaced by badges that query the registries directly
- deprecation notes link the migration guide; the guide itself fixed

Additions:
- "See also" sections, cross-references, 25 runnable examples, 12
  Mermaid diagrams, new API pages for json_pointer::operator<=> and
  byte_container_with_subtype::operator==/!=
- landing page, guides for untrusted input and performance
- "unreleased" badge after versions newer than the latest release

Checks:
- strict documentation build (broken links/anchors fail it); CI and
  the publish workflow fetch the full history the build needs
- weekly external link check, Mermaid syntax check in CI
- check_structure.py: example titles, heading levels, alt texts,
  header links, docset index coverage; its unused-example check works
  again
- all examples produce the same output on every platform

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Keep the customer links that could not be fixed

A dead link on the customers page is still the evidence of where the
use of the library was documented. Keep the original URLs of the entries
without a working replacement (Marne, Cisco Webex Desk Camera, Philips
Hue, CyberArk) and exclude exactly these URLs from the link check.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Correct the duplicate-key recipe's claim about SAX positions

The SAX interface's key() receives no position either; only parse_error()
does. Also note that the recipe does not report the path to the repeated
key (see discussion #5085).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Say the library is available as a single header and mention json_fwd.hpp

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Correct documentation errors found while hunting for bugs

- patch/patch_inplace: list the JSON pointer errors parse_error.106-109
  and out_of_range.402/404, and quote the actual parse_error.105 message.
- unflatten: list parse_error.106/107/108 and out_of_range.404.
- to_bson: list out_of_range.415 (binary subtype above 255) and note
  that 412 and 415 are new in 3.13.0.
- to_string: state that string_t must be convertible to std::string, also
  in the StringType requirements table.
- JSON Lines: a `while (input >> j)` loop also throws after the last value
  for concatenated JSON values; show a loop that works for both.
- BON8: a string gets 0xFF only if nothing follows it in the message; a
  string at the end of an array or object is ended by 0xFE.
- custom_string_type.hpp: add operator+=(char), which the "Always
  required" list asks for (json_pointer::to_string, flatten, unflatten,
  and diff did not compile), and an ADL int_to_string for diff and items.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Cache the release headers with functools.lru_cache

Codacy (Pylint) flagged the mutable default argument that header() used
as its cache. functools.lru_cache keeps the same memoization without it.
The script's output is unchanged.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-02 11:32:15 +02:00
Niels LohmannandClaude Sonnet 5 ed513715a8 Document that a NUL byte in the input is treated as end of input (#5534)
* docs: document that a NUL byte in the input is treated as end of input

A NUL byte anywhere in the input - trailing, or embedded ahead of more
otherwise well-formed JSON - is currently treated the same as genuine
end of input, so parsing silently stops there instead of raising the
parse_error.101 any other unexpected byte triggers. This mirrors the
NUL-terminated-C-string convention already used when no explicit input
length is given (json::parse(const char*) already stops at strlen()),
just applied uniformly rather than only when a length is genuinely
unavailable.

This behavior predates this change and is not being altered here -
changing it would be an observable, backwards-incompatible behavior
change for any caller that (knowingly or not) depends on it, which is
not something to do silently in a patch. Documenting the current,
verified behavior as a new FAQ entry instead, so it's an intentional
and discoverable part of the contract rather than a surprise.

Fixes #5530.

Signed-off-by: Niels Lohmann <niels.lohmann@gmail.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4RQ1Ahan5YAGbnAQGjZTY

* Add JSON_STRICT_NUL_HANDLING opt-in macro for issue #5530

A NUL byte anywhere in the input is currently treated the same as real
end of input, rather than raising parse_error.101 like any other
unexpected byte (documented in the previous commit's FAQ entry). A full
unconditional fix was tried in PR #5532 but rejected as too risky to
ship by default: any caller could depend on the current behavior, even
unknowingly (e.g. a zero-padded buffer). On PR #5534, gregmarr proposed
a compile-time opt-in flag instead, and the maintainer agreed, wanting
it available now and defaulting to the corrected behavior in 4.0.0.

This mirrors the existing JSON_BRACE_INIT_COPY_SEMANTICS precedent as
closely as sensible:
- JSON_STRICT_NUL_HANDLING defaults to 0 (off); the three lexer sites
  that treat '\0' as EOF/comment-terminator are gated with
  `#if !JSON_STRICT_NUL_HANDLING` so the default-off behavior is
  byte-for-byte identical to today's.
- input_adapters.hpp's `T (&array)[N]` overload additionally trims a
  single trailing '\0' from a `char` array (e.g. a string literal like
  `json::parse("123")`) when the macro is on, so that case keeps
  working; every other element type (unsigned char, std::uint8_t, ...)
  always keeps its full extent. This intentionally does *not* reuse the
  existing strlen()-based pointer overload via SFINAE-excluding `char`
  from the array overload, as originally sketched for this change: that
  approach is ambiguous against the newer generic container overload
  added since PR #5532, and even where it compiles, strlen()-scanning a
  `char` array that is not NUL-terminated within its bounds reads past
  the end of the array (confirmed with AddressSanitizer). Trimming only
  a single trailing byte, without scanning, avoids both problems.
- Documented via docs/mkdocs/docs/api/macros/json_strict_nul_handling.md,
  linked from the macros index/nav/features page, the FAQ entry, and
  the parse/accept/operator>> reference pages.
- Tested in unit-class_parser.cpp and unit-deserialization.cpp, default
  state unguarded and opt-in state guarded. Since the library itself
  #undefs the macro at the end of json.hpp (as JSON_BRACE_INIT_COPY_SEMANTICS
  already does), a plain `#if defined(JSON_STRICT_NUL_HANDLING)` guard
  after the include never actually triggers; the tests instead capture
  the command-line value into a test-local macro before including the
  header. A few pre-existing fixtures elsewhere (std::array<uint8_t, N>
  sized one larger than their literal, relying on value-initialization
  to silently add a trailing zero byte) needed the same one-byte
  adjustment to keep passing under the opt-in behavior.

Unlike the precedent, this adds a proper `JSON_StrictNulHandling` CMake
option (rather than a raw -DCMAKE_CXX_FLAGS injection) and wires its
ci_test_strict_nul_handling target into the ci_cmake_options job matrix
in .github/workflows/ubuntu.yml, so the opt-in build is actually
exercised in CI -- closing the one gap in the precedent's own CI setup
(ci_test_brace_init_copy_semantics is defined but never referenced by
any workflow, so it has never actually run).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Clarify where JSON_STRICT_NUL_HANDLING does not reject NUL bytes

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <niels.lohmann@gmail.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 06:55:21 +02:00
Luke Banicevic dfa51af692 Enhance documentation on serializing untrusted input in dump() (#5304) 2026-07-26 08:29:31 +00:00
Niels Lohmann e9c3985f0a Fix documentation gaps found in a full GitHub Discussions review (#5264)
* 📝 Fix documentation gaps found in a full GitHub Discussions review

Reviewed all 1008 GitHub Discussions (2020-2026) for recurring questions
that better or more visible documentation would have avoided. Adds/expands
documentation for ~26 distinct gaps, including:

- New "Debugging" page collecting natvis, GDB pretty printer, LLDB status,
  and JSON_DIAGNOSTICS pointers (previously scattered/undiscoverable)
- Thread-safety and schema-validation FAQ entries
- StringType's char-based requirement (no wstring/u16string/u32string)
- Brace-initialization-yields-arrays warning directly on the constructor
  reference page (previously only in the FAQ, missed by users reading
  the constructor docs)
- std::any exclusion from get<T>(), with a manual-dispatch example
- Non-string-keyed std::map serializing as an array of pairs
- ordered_json compatibility with NLOHMANN_DEFINE_TYPE_* macros
  (already worked, was undocumented)
- std::array truncation on size-mismatched conversion (no exception)
- static_cast vs. get<std::optional<T>>() divergence
- Recipe for omitting a std::optional field instead of emitting null
- No built-in nesting-depth limit during parsing + a callback-based
  workaround recipe
- Recipe for streaming a large homogeneous array via parser callbacks
- operator>> stream-position semantics for concatenated JSON values
- JSON Pointer array-vs-object creation rule for non-existing paths
- CMake target name (nlohmann_json_modules) needed to link C++20 modules
- ESP-IDF/PlatformIO: no official package, link to a community fork
- get(key, default) as the Python dict.get() equivalent
- reserve() recipe for pre-allocating array capacity
- JSONC as an alias for the existing ignore_comments/ignore_trailing_commas
  combination (distinct from the unsupported JSON5)
- items() dereferenced-element type: decltype() idiom + detail-namespace
  stability caveat
- Various macro/type-conversion limitations (MSGPACK_DEFINE_ARRAY
  equivalent, char-array round-tripping, ADL serializer macro gap)

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* 🎨 fix format

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-07-10 16:01:08 +02:00
Niels Lohmann 521a084827 Documentation review (#5257)
* 📝 Fix documentation gaps for 3.13.0 release (todos 138-142)

- Todo 138: Add "Known issues" section to modules.md with compiler-specific troubleshooting (GCC redefinition, MSVC symbol export). Add pointer note to quality_assurance.md.
- Todo 139: Document CBOR/MessagePack half-precision float encoding for NaN/Infinity (0xF9/0xCA with exact byte sequences). Explain pre-3.13.0 double-precision bug mechanism without issue citations.
- Todo 140: Document CBOR negative-integer-overflow rejection (parse_error.112) for magnitudes exceeding int64_t range (already implemented in rev 1).
- Todo 141: Update version history in value.md and operator[].md with behavior-change details, removing issue citations per citation policy (prose is self-contained).
- Todo 142: Global sed replace of 3.12.x → 3.13.0 placeholder across all 20 documentation files.

Revision 2 incorporates feedback to reduce changelog-like issue citations. Only citations that add unique troubleshooting value are retained (#5103 for GCC workaround, #3970 for MSVC symbol export). "Known issues" section follows PR #5252's visual pattern (info admonition with bold-bullet format).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* 📝 Document integer type selection, type_name() invalid value, and std::optional get() fix

- number_handling.md: clarify that positive/negative integers select
  unsigned/signed storage based on the leading minus sign (todo 143).
- type_name.md: document the new "invalid" return value for corrupted
  JSON values (todo 145).
- get.md: note that get<std::optional<T>>() was unreachable in every
  configuration prior to 3.13.0 due to an internal macro-guard bug,
  unrelated to JSON_USE_IMPLICIT_CONVERSIONS's actual effect (todo 144).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-07-09 17:24:19 +02:00
Niels Lohmann 8d7e0046f4 Add std::format and fmt support (#5224)
* ✨ add std::format and fmt support

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* ♻️ reorganize PR

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* 💚 fix build

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* 💚 fix build

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* 💚 fix build

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-07-02 15:59:36 +02:00
SamareshSingh 62f3b41b30 fix: treat single-element brace-init as copy/move instead of wrapping in array (#5074) (#5090)
* fix: treat single-element brace-init as copy/move

When passing a json value using brace initialization with a single element
(e.g., `json j{someObj}` or `foo({someJson})`), C++ always prefers the
initializer_list constructor over the copy/move constructor. This caused
the value to be unexpectedly wrapped in a single-element array.

This bug was previously compiler-dependent (GCC wrapped, Clang did not),
but Clang 20 started matching GCC behavior, making it a universal issue.

Fix: In the initializer_list constructor, when type deduction is enabled
and the list has exactly one element, copy/move it directly instead of
creating a single-element array.

Before:
  json obj = {{"key", 1}};
  json j{obj};   // -> [{"key":1}]  (wrong: array)
  foo({obj});    // -> [{"key":1}]  (wrong: array)

After:
  json j{obj};   // -> {"key":1}   (correct: copy)
  foo({obj});    // -> {"key":1}   (correct: copy)

To explicitly create a single-element array, use json::array({value}).

Fixes the issue #5074

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>

* fix: regenerate amalgamated single_include/nlohmann/json.hpp

- Add missing comment from include/nlohmann/json.hpp explaining the
  single-element brace-init fix (issue #5074)
- Fix extra 4-space indentation in embedded json_fwd.hpp section

Regenerated by running: make amalgamate

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>

* Revert brace-init semantics change and fix amalgamation

The single-element brace-init change was a breaking change that cannot be accepted upstream. Reverted all related source, test, and doc changes, then regenerated single_include with correct indentation to pass the amalgamation CI check.

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>

* Fix: add JSON_BRACE_INIT_COPY_SEMANTICS opt-in macro for issue #5074

Single-element brace initialization wrapping in an array cannot be fixed without breaking existing code. Added JSON_BRACE_INIT_COPY_SEMANTICS as an opt-in macro (default 0) so users can enable copy/move semantics for single-element brace init without affecting anyone relying on the current behavior.

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>

* docs: add dedicated macro page and CI test target for JSON_BRACE_INIT_COPY_SEMANTICS

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>

* fix: remove compiler-dependent assertions from #5074 regression test

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>

* fix: use defined() guard for JSON_BRACE_INIT_COPY_SEMANTICS to satisfy -Wundef

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>

* docs: fix section name in json_brace_init_copy_semantics.md to pass style check

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>

* docs: move Default definition section before Notes to fix style check order

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>

---------

Signed-off-by: Samaresh Kumar Singh <ssam3003@gmail.com>
2026-05-08 08:20:24 +02:00
Niels Lohmann 9110918cf8 Fix typos (#4748)
* ✏️ fix typos

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* ✏️ address review comments

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* ✏️ address review comments

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2025-05-04 10:28:24 +02:00
Niels Lohmann 4424a0fcc1 📝 update documentation (#4723)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2025-04-05 18:54:35 +02:00
Niels LohmannandFlorian Albrechtskirchinger 7b6cf5918b Documentation change (#3672)
Co-authored-by: Florian Albrechtskirchinger <falbrechtskirchinger@gmail.com>
2022-08-05 19:51:39 +02:00
Florian Albrechtskirchinger d3e347bd2d More documentation updates for 3.11.0 (#3553)
* mkdocs: add string_view examples

* mkdocs: reference underlying operators

* mkdocs: add operator<=> examples

* mkdocs: fix style check issues

* mkdocs: tweak BJData page

* mkdocs: add CMake option hints to macros

* mkdocs: fix JSON_DISABLE_ENUM_SERIALIZATION definition

* mkdocs: fix link to unit-udt.cpp

* mkdocs: fix "Arbitrary Type Conversions" title

* mkdocs: link to api/macros/*.md instead of features/macros.md

* mkdocs: document JSON_DisableEnumSerialization CMake option

* mkdocs: encode required C++ standard in example files

* docset: detect gsed/sed

* docset: update index

* docset: fix CSS patching

* docset: add list_missing_pages make target

* docset: add list_removed_paths make target

* docset: replace page titles with name from index

* docset: add install target for Zeal docset browser

* Use GCC_TOOL in ci_test_documentation target
2022-07-31 14:05:58 +02:00
Niels Lohmann b21c345179 Reorganize directories (#3462)
* 🚚 move files
* 🚚 rename doc folder to docs
* 🚚 rename test folder to tests
2022-05-01 09:41:50 +02:00