Skip to content
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

Add assertion if nullptr is passed to parse function #3593

Merged
merged 14 commits into from
Jul 22, 2022
Merged
7 changes: 6 additions & 1 deletion docs/mkdocs/docs/api/basic_json/accept.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Unlike the [`parse`](parse.md) function, this function neither throws an excepti
: A compatible input, for instance:

- an `std::istream` object
- a `FILE` pointer
- a `FILE` pointer (must not be null)
- a C-style array of characters
- a pointer to a null-terminated string of single byte characters
- a `std::string`
Expand Down Expand Up @@ -72,6 +72,11 @@ Linear in the length of the input. The parser is a predictive LL(1) parser.

(1) A UTF-8 byte order mark is silently ignored.

!!! danger "Runtime assertion"

The precondition that a passed `#!cpp FILE` pointer must not be null is enforced with a
[runtime assertion](../../features/assertions.md).

## Examples

??? example
Expand Down
14 changes: 13 additions & 1 deletion docs/mkdocs/docs/api/basic_json/parse.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ static basic_json parse(IteratorType first, IteratorType last,
: A compatible input, for instance:

- an `std::istream` object
- a `FILE` pointer
- a `FILE` pointer (must not be null)
- a C-style array of characters
- a pointer to a null-terminated string of single byte characters
- a `std::string`
Expand Down Expand Up @@ -71,6 +71,13 @@ Deserialized JSON value; in case of a parse error and `allow_exceptions` set to

Strong guarantee: if an exception is thrown, there are no changes in the JSON value.

## Exceptions

- Throws [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token.
- Throws [`parse_error.102`](../../home/exceptions.md#jsonexceptionparse_error102) if to_unicode fails or surrogate
error.
- Throws [`parse_error.103`](../../home/exceptions.md#jsonexceptionparse_error103) if to_unicode fails.

## Complexity

Linear in the length of the input. The parser is a predictive LL(1) parser. The complexity can be higher if the parser
Expand All @@ -81,6 +88,11 @@ super-linear complexity.

(1) A UTF-8 byte order mark is silently ignored.

!!! danger "Runtime assertion"

The precondition that a passed `#!cpp FILE` pointer must not be null is enforced with a
[runtime assertion](../../features/assertions.md).

## Examples

??? example "Parsing from a character array"
Expand Down
27 changes: 27 additions & 0 deletions docs/mkdocs/docs/features/assertions.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,30 @@ behavior and yields a runtime assertion.
```
Assertion failed: (m_object != nullptr), function operator++, file iter_impl.hpp, line 368.
```

### Reading from a null `FILE` pointer

Reading from a null `#!cpp FILE` pointer is undefined behavior and yields a runtime assertion. This can happen when
calling `#!cpp std::fopen` on a nonexistent file.

??? example "Example 4: Uninitialized iterator"

The following code will trigger an assertion at runtime:

```cpp
#include <nlohmann/json.hpp>

using json = nlohmann::json;

int main()
{
std::FILE* f = std::fopen("nonexistent_file.json", "r");
json j = json::parse(f);
}
```

Output:

```
Assertion failed: (m_file != nullptr), function file_input_adapter, file input_adapters.hpp, line 55.
```
4 changes: 3 additions & 1 deletion include/nlohmann/detail/input/input_adapters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ class file_input_adapter
JSON_HEDLEY_NON_NULL(2)
explicit file_input_adapter(std::FILE* f) noexcept
: m_file(f)
{}
{
JSON_ASSERT(m_file != nullptr);
}

// make class move-only
file_input_adapter(const file_input_adapter&) = delete;
Expand Down
4 changes: 3 additions & 1 deletion single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5936,7 +5936,9 @@ class file_input_adapter
JSON_HEDLEY_NON_NULL(2)
explicit file_input_adapter(std::FILE* f) noexcept
: m_file(f)
{}
{
JSON_ASSERT(m_file != nullptr);
}

// make class move-only
file_input_adapter(const file_input_adapter&) = delete;
Expand Down