diff --git a/docs/mkdocs/docs/api/basic_json/accept.md b/docs/mkdocs/docs/api/basic_json/accept.md index bbbac053aa..097cc8c914 100644 --- a/docs/mkdocs/docs/api/basic_json/accept.md +++ b/docs/mkdocs/docs/api/basic_json/accept.md @@ -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` @@ -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 diff --git a/docs/mkdocs/docs/api/basic_json/parse.md b/docs/mkdocs/docs/api/basic_json/parse.md index 92808cd6be..e0aaf956ba 100644 --- a/docs/mkdocs/docs/api/basic_json/parse.md +++ b/docs/mkdocs/docs/api/basic_json/parse.md @@ -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` @@ -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 @@ -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" diff --git a/docs/mkdocs/docs/features/assertions.md b/docs/mkdocs/docs/features/assertions.md index a0b1187224..2bad62e81d 100644 --- a/docs/mkdocs/docs/features/assertions.md +++ b/docs/mkdocs/docs/features/assertions.md @@ -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 + + 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. + ``` diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index 2bc49aa2e9..a034a6df68 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -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; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index cc5562d062..5cc85b33ef 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -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;