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
2 changes: 1 addition & 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 (will throw [json.exception.parse_error.116](../../home/exceptions.md#jsonexceptionparse_error116) if passed pointer is `#!cpp nullptr`)
nlohmann marked this conversation as resolved.
Show resolved Hide resolved
- a C-style array of characters
- a pointer to a null-terminated string of single byte characters
- a `std::string`
Expand Down
10 changes: 10 additions & 0 deletions docs/mkdocs/docs/home/exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,16 @@ A UBJSON high-precision number could not be parsed.
[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A
```

### json.exception.parse_error.116

A `#!cpp FILE*` pointer passed to the [parse](../api/basic_json/parse.md) function is `#!cpp nullptr`; that is, a previous call to `#!cpp std::fopen` failed.
nlohmann marked this conversation as resolved.
Show resolved Hide resolved

!!! failure "Example message"

```
[json.exception.parse_error.116] parse error: input file is invalid: No such file or directory
```

## Iterator errors

This exception is thrown if iterators passed to a library function do not match
Expand Down
13 changes: 10 additions & 3 deletions include/nlohmann/detail/input/input_adapters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
#pragma once

#include <array> // array
#include <cerrno> // errno
#include <cstddef> // size_t
#include <cstring> // strlen
#include <cstring> // strlen, strerror
#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
#include <memory> // shared_ptr, make_shared, addressof
#include <numeric> // accumulate
Expand All @@ -24,6 +25,7 @@
#endif // JSON_NO_IO

#include <nlohmann/detail/iterators/iterator_traits.hpp>
#include <nlohmann/detail/exceptions.hpp>
#include <nlohmann/detail/macro_scope.hpp>

namespace nlohmann
Expand All @@ -48,9 +50,14 @@ class file_input_adapter
using char_type = char;

JSON_HEDLEY_NON_NULL(2)
explicit file_input_adapter(std::FILE* f) noexcept
explicit file_input_adapter(std::FILE* f)
: m_file(f)
{}
{
if (m_file == nullptr)
{
JSON_THROW(parse_error::create(116, 0, detail::concat("input file is invalid: ", reinterpret_cast<const char*>(std::strerror(errno))), nullptr));
nlohmann marked this conversation as resolved.
Show resolved Hide resolved
}
}

// make class move-only
file_input_adapter(const file_input_adapter&) = delete;
Expand Down
14 changes: 11 additions & 3 deletions single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5893,8 +5893,9 @@ std::size_t hash(const BasicJsonType& j)


#include <array> // array
#include <cerrno> // errno
#include <cstddef> // size_t
#include <cstring> // strlen
#include <cstring> // strlen, strerror
#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
#include <memory> // shared_ptr, make_shared, addressof
#include <numeric> // accumulate
Expand All @@ -5909,6 +5910,8 @@ std::size_t hash(const BasicJsonType& j)

// #include <nlohmann/detail/iterators/iterator_traits.hpp>

// #include <nlohmann/detail/exceptions.hpp>

// #include <nlohmann/detail/macro_scope.hpp>


Expand All @@ -5934,9 +5937,14 @@ class file_input_adapter
using char_type = char;

JSON_HEDLEY_NON_NULL(2)
explicit file_input_adapter(std::FILE* f) noexcept
explicit file_input_adapter(std::FILE* f)
: m_file(f)
{}
{
if (m_file == nullptr)
{
JSON_THROW(parse_error::create(116, 0, detail::concat("input file is invalid: ", reinterpret_cast<const char*>(std::strerror(errno))), nullptr));
}
}

// make class move-only
file_input_adapter(const file_input_adapter&) = delete;
Expand Down
7 changes: 7 additions & 0 deletions tests/src/unit-deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,13 @@ TEST_CASE("deserialization")
{
CHECK_THROWS_WITH_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, "[json.exception.parse_error.101] parse error at line 1, column 29: syntax error while parsing array - unexpected end of input; expected ']'", json::parse_error&);
}

SECTION("FILE*")
{
std::FILE* f = std::fopen("nonexisting_file", "r"); // NOTLINT(cppcoreguidelines-owning-memory)
json _;
CHECK_THROWS_WITH_AS(_ = json::parse(f), "[json.exception.parse_error.116] parse error: input file is invalid: No such file or directory", json::parse_error&);
}
}

SECTION("contiguous containers")
Expand Down