1
0
mirror of https://github.com/nlohmann/json.git synced 2025-10-27 23:35:55 +03:00

Fixes #4854 Explicitly handle nullptr in sax_parse (#4873)

* handle nullptr explicitly

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* add test

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* make amalgamate

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* Fix formatting

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* move sax parse test to relevant unit test file

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* extend exceptions.md to include other_error.502

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* Better exception messages

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* link sax_parse function

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* fix string

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* amalgamate

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* fix clang-tidy checks

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* cover valid handler with no throw

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* Add tests for other two overloads

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* cover overload with valid sax handler

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* pass an rvalue

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* ignore -Wtautological-pointer-compare

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* ignore clang-analyzer-core.NonNullParamChecker

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* ignore gcc -Wnonnull-compare

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* ignore undefined-behaviour-sanitizer

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* nest directives to ignore sanitizer errors

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

* use elif

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>

---------

Signed-off-by: Nikhil <nikhilreddydev@gmail.com>
This commit is contained in:
Nikhil
2025-08-03 00:36:01 +05:30
committed by GitHub
parent 55abcb5c0f
commit efcf9efb4f
4 changed files with 133 additions and 0 deletions

View File

@@ -900,3 +900,13 @@ A JSON Patch operation 'test' failed. The unsuccessful operation is also printed
```
[json.exception.other_error.501] unsuccessful: {"op":"test","path":"/baz","value":"bar"}
```
### json.exception.other_error.502
This exception occurs when a null pointer is passed as SAX handler in [sax_parse](../api/basic_json/sax_parse.md) function.
!!! failure "Example message"
```
[json.exception.other_error.502] SAX handler must not be null
```

View File

@@ -4122,6 +4122,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
const bool ignore_comments = false,
const bool ignore_trailing_commas = false)
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull-compare"
#endif
if (sax == nullptr)
{
JSON_THROW(other_error::create(502, "SAX handler must not be null", nullptr));
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
auto ia = detail::input_adapter(std::forward<InputType>(i));
return format == input_format_t::json
? parser(std::move(ia), nullptr, true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict)
@@ -4138,6 +4154,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
const bool ignore_comments = false,
const bool ignore_trailing_commas = false)
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull-compare"
#endif
if (sax == nullptr)
{
JSON_THROW(other_error::create(502, "SAX handler must not be null", nullptr));
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
auto ia = detail::input_adapter(std::move(first), std::move(last));
return format == input_format_t::json
? parser(std::move(ia), nullptr, true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict)
@@ -4158,6 +4190,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
const bool ignore_comments = false,
const bool ignore_trailing_commas = false)
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull-compare"
#endif
if (sax == nullptr)
{
JSON_THROW(other_error::create(502, "SAX handler must not be null", nullptr));
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
auto ia = i.get();
return format == input_format_t::json
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)

View File

@@ -24225,6 +24225,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
const bool ignore_comments = false,
const bool ignore_trailing_commas = false)
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull-compare"
#endif
if (sax == nullptr)
{
JSON_THROW(other_error::create(502, "SAX handler must not be null", nullptr));
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
auto ia = detail::input_adapter(std::forward<InputType>(i));
return format == input_format_t::json
? parser(std::move(ia), nullptr, true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict)
@@ -24241,6 +24257,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
const bool ignore_comments = false,
const bool ignore_trailing_commas = false)
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull-compare"
#endif
if (sax == nullptr)
{
JSON_THROW(other_error::create(502, "SAX handler must not be null", nullptr));
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
auto ia = detail::input_adapter(std::move(first), std::move(last));
return format == input_format_t::json
? parser(std::move(ia), nullptr, true, ignore_comments, ignore_trailing_commas).sax_parse(sax, strict)
@@ -24261,6 +24293,22 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
const bool ignore_comments = false,
const bool ignore_trailing_commas = false)
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull-compare"
#endif
if (sax == nullptr)
{
JSON_THROW(other_error::create(502, "SAX handler must not be null", nullptr));
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
auto ia = i.get();
return format == input_format_t::json
// NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)

View File

@@ -1644,6 +1644,33 @@ TEST_CASE("parser class")
SECTION("SAX parser")
{
SECTION("null sax handler")
{
# if defined(__has_feature)
#if !__has_feature(undefined_behavior_sanitizer)
const std::string s = "some_string";
SaxCountdown* p = nullptr;
CHECK_THROWS_WITH_AS(json::sax_parse(s, p), "[json.exception.other_error.502] SAX handler must not be null", json::other_error&); // NOLINT(clang-analyzer-core.NonNullParamChecker)
CHECK_THROWS_WITH_AS(json::sax_parse(s.begin(), s.end(), p), "[json.exception.other_error.502] SAX handler must not be null", json::other_error&); // NOLINT(clang-analyzer-core.NonNullParamChecker)
CHECK_THROWS_WITH_AS(json::sax_parse(nlohmann::detail::span_input_adapter(s.c_str(), s.size()), p), "[json.exception.other_error.502] SAX handler must not be null", json::other_error&); // NOLINT(clang-analyzer-core.NonNullParamChecker)
#endif
#else
const std::string s = "some_string";
SaxCountdown* p = nullptr;
CHECK_THROWS_WITH_AS(json::sax_parse(s, p), "[json.exception.other_error.502] SAX handler must not be null", json::other_error&); // NOLINT(clang-analyzer-core.NonNullParamChecker)
CHECK_THROWS_WITH_AS(json::sax_parse(s.begin(), s.end(), p), "[json.exception.other_error.502] SAX handler must not be null", json::other_error&); // NOLINT(clang-analyzer-core.NonNullParamChecker)
CHECK_THROWS_WITH_AS(json::sax_parse(nlohmann::detail::span_input_adapter(s.c_str(), s.size()), p), "[json.exception.other_error.502] SAX handler must not be null", json::other_error&); // NOLINT(clang-analyzer-core.NonNullParamChecker)
#endif
}
SECTION("valid sax handler")
{
const std::string str = "some_string";
SaxCountdown s(1);
CHECK(json::sax_parse(str, &s) == false);
CHECK(json::sax_parse(nlohmann::detail::span_input_adapter(str.c_str(), str.size()), &s) == false);
}
SECTION("} without value")
{
SaxCountdown s(1);