mirror of
https://github.com/nlohmann/json.git
synced 2026-10-01 04:00:31 +00:00
Reject integral keys for contains(), find(), and count() at compile time (#5705)
j.contains(0), j.find(0), and j.count(0) used to compile: the literal 0 is a null pointer constant, so it converts to a null const char*, and the overloads taking const typename object_t::key_type& accepted it by constructing a std::string from that null pointer, which is undefined behavior (a crash with both libc++ and libstdc++). value(0, default_value) had the same problem in C++11, where the object comparator is not transparent. Add deleted overloads for integral arguments to contains(), find() (const and non-const), count(), and value() so that these calls are compile errors in every supported language mode instead of crashing. Calls with string, string_view, json_pointer, and size-typed element access (at(), operator[](), erase()) are unaffected. Fixes #5657. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -58,6 +58,10 @@ Logarithmic in the size of the JSON object.
|
||||
|
||||
- This method always returns `#!cpp false` when executed on a JSON type that is not an object.
|
||||
- This method can be executed on any JSON value type.
|
||||
- Calling this function with an integer argument (for example, `#!cpp contains(0)`) does not compile: such an argument
|
||||
would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when
|
||||
constructing a `#!cpp std::string` for the object key. To check for an array element instead, use [`at`](at.md),
|
||||
[`operator[]`](operator%5B%5D.md), or compare against [`size`](size.md).
|
||||
|
||||
!!! info "Postconditions"
|
||||
|
||||
@@ -117,3 +121,5 @@ Logarithmic in the size of the JSON object.
|
||||
1. Added in version 3.11.0.
|
||||
2. Added in version 3.6.0. Extended template `KeyType` to support comparable types in version 3.11.0.
|
||||
3. Added in version 3.7.0.
|
||||
4. Deleted overloads for integral key types added in version 3.13.0 to reject such calls at compile time instead of
|
||||
causing undefined behavior at runtime.
|
||||
|
||||
@@ -40,7 +40,11 @@ Logarithmic in the size of the JSON object.
|
||||
|
||||
## Notes
|
||||
|
||||
This method always returns `0` when executed on a JSON type that is not an object.
|
||||
- This method always returns `0` when executed on a JSON type that is not an object.
|
||||
- Calling this function with an integer argument (for example, `#!cpp count(0)`) does not compile: such an argument
|
||||
would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when
|
||||
constructing a `#!cpp std::string` for the object key. To check for an array element instead, use [`at`](at.md),
|
||||
[`operator[]`](operator%5B%5D.md), or compare against [`size`](size.md).
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -81,3 +85,5 @@ This method always returns `0` when executed on a JSON type that is not an objec
|
||||
|
||||
1. Added in version 3.11.0.
|
||||
2. Added in version 1.0.0. Changed parameter `key` type to `KeyType&&` in version 3.11.0.
|
||||
3. Deleted overload for integral key types added in version 3.13.0 to reject such calls at compile time instead of
|
||||
causing undefined behavior at runtime.
|
||||
|
||||
@@ -44,7 +44,11 @@ Logarithmic in the size of the JSON object.
|
||||
|
||||
## Notes
|
||||
|
||||
This method always returns `end()` when executed on a JSON type that is not an object.
|
||||
- This method always returns `end()` when executed on a JSON type that is not an object.
|
||||
- Calling this function with an integer argument (for example, `#!cpp find(0)`) does not compile: such an argument
|
||||
would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when
|
||||
constructing a `#!cpp std::string` for the object key. To access an array element instead, use [`at`](at.md),
|
||||
[`operator[]`](operator%5B%5D.md), or compare against [`size`](size.md).
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -85,3 +89,5 @@ This method always returns `end()` when executed on a JSON type that is not an o
|
||||
|
||||
1. Added in version 3.11.0.
|
||||
2. Added in version 1.0.0. Changed to support comparable types in version 3.11.0.
|
||||
3. Deleted overloads for integral key types added in version 3.13.0 to reject such calls at compile time instead of
|
||||
causing undefined behavior at runtime.
|
||||
|
||||
@@ -52,6 +52,14 @@ This is equivalent to Python's `dict.get(key, default)`.
|
||||
- Unlike [`operator[]`](operator[].md), this function does not implicitly add an element to the position defined by
|
||||
`key`/`ptr` key. This function is furthermore also applicable to const objects.
|
||||
|
||||
!!! note "Integer keys"
|
||||
|
||||
Calling this function with an integer `key` argument (for example, `#!cpp value(0, 1)`) does not compile in
|
||||
C++11, where `object_comparator_t` is not transparent: such an argument would otherwise implicitly convert to a
|
||||
null `#!cpp const char*` and, from there, cause undefined behavior when constructing a `#!cpp std::string` for the
|
||||
object key. To access an array element with a default value, use [`at`](at.md) together with a `#!cpp try`/`#!cpp
|
||||
catch` block, or compare against [`size`](size.md) instead.
|
||||
|
||||
## Template parameters
|
||||
|
||||
`KeyType`
|
||||
@@ -184,7 +192,9 @@ changes to any JSON value.
|
||||
|
||||
## Version history
|
||||
|
||||
1. Added in version 1.0.0. Changed parameter `default_value` type from `const ValueType&` to `ValueType&&` in version 3.11.0.
|
||||
1. Added in version 1.0.0. Changed parameter `default_value` type from `const ValueType&` to `ValueType&&` in version
|
||||
3.11.0. Deleted overload for integral key types added in version 3.13.0 to reject such calls at compile time
|
||||
instead of causing undefined behavior at runtime.
|
||||
2. Added in version 3.11.0. Made `ValueType` the first template parameter in version 3.11.2.
|
||||
3. Added in version 2.0.2. Extended to work with arrays in version 3.13.0, including fixing an issue where resolving
|
||||
`ptr` through an array unexpectedly threw `out_of_range` instead of returning the resolved element (or
|
||||
|
||||
Reference in New Issue
Block a user