diff --git a/docs/mkdocs/docs/home/exceptions.md b/docs/mkdocs/docs/home/exceptions.md index cfa4f57a2..4b6eb88b3 100644 --- a/docs/mkdocs/docs/home/exceptions.md +++ b/docs/mkdocs/docs/home/exceptions.md @@ -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 + ``` diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 55ec39d24..a49a28b8a 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -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(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) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 1fd570576..e66265542 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -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(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) diff --git a/tests/src/unit-class_parser.cpp b/tests/src/unit-class_parser.cpp index 394bad432..58d27aca8 100644 --- a/tests/src/unit-class_parser.cpp +++ b/tests/src/unit-class_parser.cpp @@ -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);