NJF-01#

The service accepts the literal name null.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;null] (TSF/tests/unit-class_parser_core.cpp)

SECTION("null")
{
    CHECK(accept_helper("null"));
}
  • cpp-testsuite: [/nst_json_testsuite/test_parsing/y_structure_lonely_null.json]

    • JSON Testsuite: /nst_json_testsuite/test_parsing/y_structure_lonely_null.json

    null
    
    • cpp-test: [nst’s JSONTestSuite;test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_null.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json j;
            CHECK_NOTHROW(f >> j);
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_structure_lonely_null.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_structure_lonely_null.json

    null
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_lonely_null.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • function: [lexer::scan_literal] (include/nlohmann/detail/input/lexer.hpp)

    • Description: function to verify whether a candidate literal coincides with its expected value; here called with literal_text = [‘n’,’u’,’l’,’l’].

token_type scan_literal(const char_type* literal_text, const std::size_t length,
                        token_type return_type)
{
    JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
    for (std::size_t i = 1; i < length; ++i)
    {
        if (JSON_HEDLEY_UNLIKELY(char_traits<char_type>::to_char_type(get()) != literal_text[i]))
        {
            error_message = "invalid literal";
            return token_type::parse_error;
        }
    }
    return return_type;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-02#

The service accepts the literal name true.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;true] (TSF/tests/unit-class_parser_core.cpp)

SECTION("true")
{
    CHECK(accept_helper("true"));
}
  • cpp-test: [deserialization;contiguous containers;directly] (tests/src/unit-deserialization.cpp)

SECTION("directly")
{
    SECTION("from std::vector")
    {
        std::vector<uint8_t> const v = {'t', 'r', 'u', 'e'};
        CHECK(json::parse(v) == json(true));
        CHECK(json::accept(v));

        SaxEventLogger l;
        CHECK(json::sax_parse(v, &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
    }

    SECTION("from std::array")
    {
        std::array<uint8_t, 5> const v { {'t', 'r', 'u', 'e'} };
        CHECK(json::parse(v) == json(true));
        CHECK(json::accept(v));

        SaxEventLogger l;
        CHECK(json::sax_parse(v, &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
    }

    SECTION("from array")
    {
        uint8_t v[] = {'t', 'r', 'u', 'e'}; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
        CHECK(json::parse(v) == json(true));
        CHECK(json::accept(v));

        SaxEventLogger l;
        CHECK(json::sax_parse(v, &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
    }

    SECTION("from chars")
    {
        auto* v = new uint8_t[5]; // NOLINT(cppcoreguidelines-owning-memory)
        v[0] = 't';
        v[1] = 'r';
        v[2] = 'u';
        v[3] = 'e';
        v[4] = '\0';
        CHECK(json::parse(v) == json(true));
        CHECK(json::accept(v));

        SaxEventLogger l;
        CHECK(json::sax_parse(v, &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"boolean(true)"}));

        delete[] v; // NOLINT(cppcoreguidelines-owning-memory)
    }

    SECTION("from std::string")
    {
        std::string const v = {'t', 'r', 'u', 'e'};
        CHECK(json::parse(v) == json(true));
        CHECK(json::accept(v));

        SaxEventLogger l;
        CHECK(json::sax_parse(v, &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
    }

    SECTION("from std::initializer_list")
    {
        std::initializer_list<uint8_t> const v = {'t', 'r', 'u', 'e'};
        CHECK(json::parse(v) == json(true));
        CHECK(json::accept(v));

        SaxEventLogger l;
        CHECK(json::sax_parse(v, &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"boolean(true)"}));
    }

    SECTION("empty container")
    {
        std::vector<uint8_t> const v;
        json _;
        CHECK_THROWS_AS(_ = json::parse(v), json::parse_error&);
        CHECK(!json::accept(v));

        SaxEventLogger l;
        CHECK(!json::sax_parse(v, &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(1)"}));
    }
}
  • cpp-testsuite: [/nst_json_testsuite/test_parsing/y_structure_lonely_true.json]

    • JSON Testsuite: /nst_json_testsuite/test_parsing/y_structure_lonely_true.json

    true
    
    • cpp-test: [nst’s JSONTestSuite;test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_true.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json j;
            CHECK_NOTHROW(f >> j);
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_structure_lonely_true.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_structure_lonely_true.json

    true
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_lonely_true.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • function: [lexer::scan_literal] (include/nlohmann/detail/input/lexer.hpp)

    • Description: function to verify whether a candidate literal coincides with its expected value; here called with literal_text = [‘t’,’r’,’u’,’e’].

token_type scan_literal(const char_type* literal_text, const std::size_t length,
                        token_type return_type)
{
    JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
    for (std::size_t i = 1; i < length; ++i)
    {
        if (JSON_HEDLEY_UNLIKELY(char_traits<char_type>::to_char_type(get()) != literal_text[i]))
        {
            error_message = "invalid literal";
            return token_type::parse_error;
        }
    }
    return return_type;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-03#

The service accepts the literal name false.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;false] (TSF/tests/unit-class_parser_core.cpp)

SECTION("false")
{
    CHECK(accept_helper("false"));
}
  • cpp-testsuite: [/nst_json_testsuite/test_parsing/y_structure_lonely_false.json]

    • JSON Testsuite: /nst_json_testsuite/test_parsing/y_structure_lonely_false.json

    false
    
    • cpp-test: [nst’s JSONTestSuite;test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_structure_lonely_false.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json j;
            CHECK_NOTHROW(f >> j);
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_structure_lonely_false.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_structure_lonely_false.json

    false
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_lonely_false.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • function: [lexer::scan_literal] (include/nlohmann/detail/input/lexer.hpp)

    • Description: function to verify whether a candidate literal coincides with its expected value; here called with literal_text = [‘f’,’a’,’l’,’s’,’e’].

token_type scan_literal(const char_type* literal_text, const std::size_t length,
                        token_type return_type)
{
    JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
    for (std::size_t i = 1; i < length; ++i)
    {
        if (JSON_HEDLEY_UNLIKELY(char_traits<char_type>::to_char_type(get()) != literal_text[i]))
        {
            error_message = "invalid literal";
            return token_type::parse_error;
        }
    }
    return return_type;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-04#

The service does not accept any other literal name.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;parse errors (accept)] (TSF/tests/unit-class_parser_core.cpp)

SECTION("parse errors (accept)")
{
    // unexpected end of number
    CHECK(accept_helper("0.") == false);
    CHECK(accept_helper("-") == false);
    CHECK(accept_helper("--") == false);
    CHECK(accept_helper("-0.") == false);
    CHECK(accept_helper("-.") == false);
    CHECK(accept_helper("-:") == false);
    CHECK(accept_helper("0.:") == false);
    CHECK(accept_helper("e.") == false);
    CHECK(accept_helper("1e.") == false);
    CHECK(accept_helper("1e/") == false);
    CHECK(accept_helper("1e:") == false);
    CHECK(accept_helper("1E.") == false);
    CHECK(accept_helper("1E/") == false);
    CHECK(accept_helper("1E:") == false);

    // unexpected end of null
    CHECK(accept_helper("n") == false);
    CHECK(accept_helper("nu") == false);
    CHECK(accept_helper("nul") == false);

    // unexpected end of true
    CHECK(accept_helper("t") == false);
    CHECK(accept_helper("tr") == false);
    CHECK(accept_helper("tru") == false);

    // unexpected end of false
    CHECK(accept_helper("f") == false);
    CHECK(accept_helper("fa") == false);
    CHECK(accept_helper("fal") == false);
    CHECK(accept_helper("fals") == false);

    // missing/unexpected end of array
    CHECK(accept_helper("[") == false);
    CHECK(accept_helper("[1") == false);
    CHECK(accept_helper("[1,") == false);
    CHECK(accept_helper("[1,]") == false);
    CHECK(accept_helper("]") == false);

    // missing/unexpected end of object
    CHECK(accept_helper("{") == false);
    CHECK(accept_helper("{\"foo\"") == false);
    CHECK(accept_helper("{\"foo\":") == false);
    CHECK(accept_helper("{\"foo\":}") == false);
    CHECK(accept_helper("{\"foo\":1,}") == false);
    CHECK(accept_helper("}") == false);

    // missing/unexpected end of string
    CHECK(accept_helper("\"") == false);
    CHECK(accept_helper("\"\\\"") == false);
    CHECK(accept_helper("\"\\u\"") == false);
    CHECK(accept_helper("\"\\u0\"") == false);
    CHECK(accept_helper("\"\\u01\"") == false);
    CHECK(accept_helper("\"\\u012\"") == false);
    CHECK(accept_helper("\"\\u") == false);
    CHECK(accept_helper("\"\\u0") == false);
    CHECK(accept_helper("\"\\u01") == false);
    CHECK(accept_helper("\"\\u012") == false);

    // unget of newline
    CHECK(parser_helper("\n123\n") == 123);

    // invalid escapes
    for (int c = 1; c < 128; ++c)
    {
        auto s = std::string("\"\\") + std::string(1, static_cast<char>(c)) + "\"";

        switch (c)
        {
            // valid escapes
            case ('"'):
            case ('\\'):
            case ('/'):
            case ('b'):
            case ('f'):
            case ('n'):
            case ('r'):
            case ('t'):
            {
                CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept());
                break;
            }

            // \u must be followed with four numbers, so we skip it here
            case ('u'):
            {
                break;
            }

            // any other combination of backslash and character is invalid
            default:
            {
                CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept() == false);
                break;
            }
        }
    }

    // invalid \uxxxx escapes
    {
        // check whether character is a valid hex character
        const auto valid = [](int c)
        {
            switch (c)
            {
                case ('0'):
                case ('1'):
                case ('2'):
                case ('3'):
                case ('4'):
                case ('5'):
                case ('6'):
                case ('7'):
                case ('8'):
                case ('9'):
                case ('a'):
                case ('b'):
                case ('c'):
                case ('d'):
                case ('e'):
                case ('f'):
                case ('A'):
                case ('B'):
                case ('C'):
                case ('D'):
                case ('E'):
                case ('F'):
                {
                    return true;
                }

                default:
                {
                    return false;
                }
            }
        };

        for (int c = 1; c < 128; ++c)
        {
            std::string const s = "\"\\u";

            // create a string with the iterated character at each position
            const auto s1 = s + "000" + std::string(1, static_cast<char>(c)) + "\"";
            const auto s2 = s + "00" + std::string(1, static_cast<char>(c)) + "0\"";
            const auto s3 = s + "0" + std::string(1, static_cast<char>(c)) + "00\"";
            const auto s4 = s + std::string(1, static_cast<char>(c)) + "000\"";

            if (valid(c))
            {
                CAPTURE(s1)
                CHECK(json::parser(nlohmann::detail::input_adapter(s1)).accept());
                CAPTURE(s2)
                CHECK(json::parser(nlohmann::detail::input_adapter(s2)).accept());
                CAPTURE(s3)
                CHECK(json::parser(nlohmann::detail::input_adapter(s3)).accept());
                CAPTURE(s4)
                CHECK(json::parser(nlohmann::detail::input_adapter(s4)).accept());
            }
            else
            {
                CAPTURE(s1)
                CHECK(json::parser(nlohmann::detail::input_adapter(s1)).accept() == false);

                CAPTURE(s2)
                CHECK(json::parser(nlohmann::detail::input_adapter(s2)).accept() == false);

                CAPTURE(s3)
                CHECK(json::parser(nlohmann::detail::input_adapter(s3)).accept() == false);

                CAPTURE(s4)
                CHECK(json::parser(nlohmann::detail::input_adapter(s4)).accept() == false);
            }
        }
    }

    // missing part of a surrogate pair
    CHECK(accept_helper("\"\\uD80C\"") == false);
    // invalid surrogate pair
    CHECK(accept_helper("\"\\uD80C\\uD80C\"") == false);
    CHECK(accept_helper("\"\\uD80C\\u0000\"") == false);
    CHECK(accept_helper("\"\\uD80C\\uFFFF\"") == false);
}
  • cpp-testsuite: [/nst_json_testsuite/test_parsing/n_incomplete_false.json, /nst_json_testsuite/test_parsing/n_incomplete_null.json, /nst_json_testsuite/test_parsing/n_incomplete_true.json, /nst_json_testsuite/test_parsing/n_structure_number_with_trailing_garbage.json]

    • JSON Testsuite: /nst_json_testsuite/test_parsing/n_incomplete_false.json

    [fals]
    
    • JSON Testsuite: /nst_json_testsuite/test_parsing/n_incomplete_null.json

    [nul]
    
    • JSON Testsuite: /nst_json_testsuite/test_parsing/n_incomplete_true.json

    [tru]
    
    • JSON Testsuite: /nst_json_testsuite/test_parsing/n_structure_number_with_trailing_garbage.json

    2@
    
    • cpp-test: [nst’s JSONTestSuite;test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_incomplete_false.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_incomplete_null.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_incomplete_true.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_number_with_trailing_garbage.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_incomplete_false.json, /nst_json_testsuite2/test_parsing/n_incomplete_null.json, /nst_json_testsuite2/test_parsing/n_incomplete_true.json, /nst_json_testsuite2/test_parsing/n_structure_capitalized_True.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_incomplete_false.json

    [fals]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_incomplete_null.json

    [nul]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_incomplete_true.json

    [tru]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_capitalized_True.json

    [True]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_incomplete_false.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_incomplete_null.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_incomplete_true.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_capitalized_True.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [accept;unicode] (TSF/tests/unit-literals.cpp)

SECTION("unicode")
{
    CHECK(json::accept("\u0074\u0072\u0075\u0065")); // true
    CHECK(json::accept("\u0066\u0061\u006c\u0073\u0065")); // false
    CHECK(json::accept("\u006e\u0075\u006c\u006c"));
}
  • cpp-test: [accept;capitalisation] (TSF/tests/unit-literals.cpp)

SECTION("capitalisation")
{
    SECTION("true")
    {
        CHECK(!json::accept("True"));
        CHECK(!json::accept("tRue"));
        CHECK(!json::accept("trUe"));
        CHECK(!json::accept("truE"));
        CHECK(!json::accept("TRue"));
        CHECK(!json::accept("TrUe"));
        CHECK(!json::accept("TruE"));
        CHECK(!json::accept("tRUe"));
        CHECK(!json::accept("tRuE"));
        CHECK(!json::accept("trUE"));
        CHECK(!json::accept("TRUe"));
        CHECK(!json::accept("TRuE"));
        CHECK(!json::accept("TrUE"));
        CHECK(!json::accept("tRUE"));
        CHECK(!json::accept("TRUE"));
    }
    SECTION("null")
    {
        CHECK(!json::accept("Null"));
        CHECK(!json::accept("nUll"));
        CHECK(!json::accept("nuLl"));
        CHECK(!json::accept("nulL"));
        CHECK(!json::accept("NUll"));
        CHECK(!json::accept("NuLl"));
        CHECK(!json::accept("NulL"));
        CHECK(!json::accept("nULl"));
        CHECK(!json::accept("nUlL"));
        CHECK(!json::accept("nuLL"));
        CHECK(!json::accept("NULl"));
        CHECK(!json::accept("NUlL"));
        CHECK(!json::accept("NuLL"));
        CHECK(!json::accept("nULL"));
        CHECK(!json::accept("NULL"));
    }
    SECTION("false")
    {            
        CHECK(!json::accept("False"));
        CHECK(!json::accept("fAlse"));
        CHECK(!json::accept("FAlse"));
        CHECK(!json::accept("faLse"));
        CHECK(!json::accept("FaLse"));
        CHECK(!json::accept("fALse"));
        CHECK(!json::accept("FALse"));
        CHECK(!json::accept("falSe"));
        CHECK(!json::accept("FalSe"));
        CHECK(!json::accept("fAlSe"));
        CHECK(!json::accept("FAlSe"));
        CHECK(!json::accept("faLSe"));
        CHECK(!json::accept("FaLSe"));
        CHECK(!json::accept("fALSe"));
        CHECK(!json::accept("FALSe"));
        CHECK(!json::accept("falsE"));
        CHECK(!json::accept("FalsE"));
        CHECK(!json::accept("fAlsE"));
        CHECK(!json::accept("FAlsE"));
        CHECK(!json::accept("faLsE"));
        CHECK(!json::accept("FaLsE"));
        CHECK(!json::accept("fALsE"));
        CHECK(!json::accept("FALsE"));
        CHECK(!json::accept("falSE"));
        CHECK(!json::accept("FalSE"));
        CHECK(!json::accept("fAlSE"));
        CHECK(!json::accept("FAlSE"));
        CHECK(!json::accept("faLSE"));
        CHECK(!json::accept("FaLSE"));
        CHECK(!json::accept("fALSE"));
        CHECK(!json::accept("FALSE"));
    }
}
  • cpp-test: [accept;illegal literals] (TSF/tests/unit-literals.cpp)

SECTION("illegal literals")
{
    SECTION("nil")
    {
        CHECK(!json::accept("nil"));
        CHECK(!json::accept("Nil"));
        CHECK(!json::accept("nIl"));
        CHECK(!json::accept("NIl"));
        CHECK(!json::accept("niL"));
        CHECK(!json::accept("NiL"));
        CHECK(!json::accept("nIL"));
        CHECK(!json::accept("NIL"));
    }
    SECTION("truth")
    {
        CHECK(!json::accept("truth"));
        CHECK(!json::accept("Truth"));
        CHECK(!json::accept("tRuth"));
        CHECK(!json::accept("TRuth"));
        CHECK(!json::accept("trUth"));
        CHECK(!json::accept("TrUth"));
        CHECK(!json::accept("tRUth"));
        CHECK(!json::accept("TRUth"));
        CHECK(!json::accept("truTh"));
        CHECK(!json::accept("TruTh"));
        CHECK(!json::accept("tRuTh"));
        CHECK(!json::accept("TRuTh"));
        CHECK(!json::accept("trUTh"));
        CHECK(!json::accept("TrUTh"));
        CHECK(!json::accept("tRUTh"));
        CHECK(!json::accept("TRUTh"));
        CHECK(!json::accept("trutH"));
        CHECK(!json::accept("TrutH"));
        CHECK(!json::accept("tRutH"));
        CHECK(!json::accept("TRutH"));
        CHECK(!json::accept("trUtH"));
        CHECK(!json::accept("TrUtH"));
        CHECK(!json::accept("tRUtH"));
        CHECK(!json::accept("TRUtH"));
        CHECK(!json::accept("truTH"));
        CHECK(!json::accept("TruTH"));
        CHECK(!json::accept("tRuTH"));
        CHECK(!json::accept("TRuTH"));
        CHECK(!json::accept("trUTH"));
        CHECK(!json::accept("TrUTH"));
        CHECK(!json::accept("tRUTH"));
        CHECK(!json::accept("TRUTH"));
    }
    SECTION("const")
    {
        CHECK(!json::accept("const"));
        CHECK(!json::accept("Const"));
        CHECK(!json::accept("cOnst"));
        CHECK(!json::accept("COnst"));
        CHECK(!json::accept("coNst"));
        CHECK(!json::accept("CoNst"));
        CHECK(!json::accept("cONst"));
        CHECK(!json::accept("CONst"));
        CHECK(!json::accept("conSt"));
        CHECK(!json::accept("ConSt"));
        CHECK(!json::accept("cOnSt"));
        CHECK(!json::accept("COnSt"));
        CHECK(!json::accept("coNSt"));
        CHECK(!json::accept("CoNSt"));
        CHECK(!json::accept("cONSt"));
        CHECK(!json::accept("CONSt"));
        CHECK(!json::accept("consT"));
        CHECK(!json::accept("ConsT"));
        CHECK(!json::accept("cOnsT"));
        CHECK(!json::accept("COnsT"));
        CHECK(!json::accept("coNsT"));
        CHECK(!json::accept("CoNsT"));
        CHECK(!json::accept("cONsT"));
        CHECK(!json::accept("CONsT"));
        CHECK(!json::accept("conST"));
        CHECK(!json::accept("ConST"));
        CHECK(!json::accept("cOnST"));
        CHECK(!json::accept("COnST"));
        CHECK(!json::accept("coNST"));
        CHECK(!json::accept("CoNST"));
        CHECK(!json::accept("cONST"));
        CHECK(!json::accept("CONST"));
    }
    SECTION("none")
    {
        CHECK(!json::accept("none"));
        CHECK(!json::accept("None"));
        CHECK(!json::accept("nOne"));
        CHECK(!json::accept("NOne"));
        CHECK(!json::accept("noNe"));
        CHECK(!json::accept("NoNe"));
        CHECK(!json::accept("nONe"));
        CHECK(!json::accept("NONe"));
        CHECK(!json::accept("nonE"));
        CHECK(!json::accept("NonE"));
        CHECK(!json::accept("nOnE"));
        CHECK(!json::accept("NOnE"));
        CHECK(!json::accept("noNE"));
        CHECK(!json::accept("NoNE"));
        CHECK(!json::accept("nONE"));
        CHECK(!json::accept("NONE"));
    }
    SECTION("self")
    {
        CHECK(!json::accept("self"));
        CHECK(!json::accept("Self"));
        CHECK(!json::accept("sElf"));
        CHECK(!json::accept("SElf"));
        CHECK(!json::accept("seLf"));
        CHECK(!json::accept("SeLf"));
        CHECK(!json::accept("sELf"));
        CHECK(!json::accept("SELf"));
        CHECK(!json::accept("selF"));
        CHECK(!json::accept("SelF"));
        CHECK(!json::accept("sElF"));
        CHECK(!json::accept("SElF"));
        CHECK(!json::accept("seLF"));
        CHECK(!json::accept("SeLF"));
        CHECK(!json::accept("sELF"));
        CHECK(!json::accept("SELF"));
    }
    SECTION("super")
    {
        CHECK(!json::accept("super"));
        CHECK(!json::accept("Super"));
        CHECK(!json::accept("sUper"));
        CHECK(!json::accept("SUper"));
        CHECK(!json::accept("suPer"));
        CHECK(!json::accept("SuPer"));
        CHECK(!json::accept("sUPer"));
        CHECK(!json::accept("SUPer"));
        CHECK(!json::accept("supEr"));
        CHECK(!json::accept("SupEr"));
        CHECK(!json::accept("sUpEr"));
        CHECK(!json::accept("SUpEr"));
        CHECK(!json::accept("suPEr"));
        CHECK(!json::accept("SuPEr"));
        CHECK(!json::accept("sUPEr"));
        CHECK(!json::accept("SUPEr"));
        CHECK(!json::accept("supeR"));
        CHECK(!json::accept("SupeR"));
        CHECK(!json::accept("sUpeR"));
        CHECK(!json::accept("SUpeR"));
        CHECK(!json::accept("suPeR"));
        CHECK(!json::accept("SuPeR"));
        CHECK(!json::accept("sUPeR"));
        CHECK(!json::accept("SUPeR"));
        CHECK(!json::accept("supER"));
        CHECK(!json::accept("SupER"));
        CHECK(!json::accept("sUpER"));
        CHECK(!json::accept("SUpER"));
        CHECK(!json::accept("suPER"));
        CHECK(!json::accept("SuPER"));
        CHECK(!json::accept("sUPER"));
        CHECK(!json::accept("SUPER"));
    }
    SECTION("this")
    {
        CHECK(!json::accept("this"));
        CHECK(!json::accept("This"));
        CHECK(!json::accept("tHis"));
        CHECK(!json::accept("THis"));
        CHECK(!json::accept("thIs"));
        CHECK(!json::accept("ThIs"));
        CHECK(!json::accept("tHIs"));
        CHECK(!json::accept("THIs"));
        CHECK(!json::accept("thiS"));
        CHECK(!json::accept("ThiS"));
        CHECK(!json::accept("tHiS"));
        CHECK(!json::accept("THiS"));
        CHECK(!json::accept("thIS"));
        CHECK(!json::accept("ThIS"));
        CHECK(!json::accept("tHIS"));
        CHECK(!json::accept("THIS"));
    }
    SECTION("undefined")
    {
        CHECK(!json::accept("undefined"));
        CHECK(!json::accept("Undefined"));
        CHECK(!json::accept("uNdefined"));
        CHECK(!json::accept("UNdefined"));
        CHECK(!json::accept("unDefined"));
        CHECK(!json::accept("UnDefined"));
        CHECK(!json::accept("uNDefined"));
        CHECK(!json::accept("UNDefined"));
        CHECK(!json::accept("undEfined"));
        CHECK(!json::accept("UndEfined"));
        CHECK(!json::accept("uNdEfined"));
        CHECK(!json::accept("UNdEfined"));
        CHECK(!json::accept("unDEfined"));
        CHECK(!json::accept("UnDEfined"));
        CHECK(!json::accept("uNDEfined"));
        CHECK(!json::accept("UNDEfined"));
        CHECK(!json::accept("undeFined"));
        CHECK(!json::accept("UndeFined"));
        CHECK(!json::accept("uNdeFined"));
        CHECK(!json::accept("UNdeFined"));
        CHECK(!json::accept("unDeFined"));
        CHECK(!json::accept("UnDeFined"));
        CHECK(!json::accept("uNDeFined"));
        CHECK(!json::accept("UNDeFined"));
        CHECK(!json::accept("undEFined"));
        CHECK(!json::accept("UndEFined"));
        CHECK(!json::accept("uNdEFined"));
        CHECK(!json::accept("UNdEFined"));
        CHECK(!json::accept("unDEFined"));
        CHECK(!json::accept("UnDEFined"));
        CHECK(!json::accept("uNDEFined"));
        CHECK(!json::accept("UNDEFined"));
        CHECK(!json::accept("undefIned"));
        CHECK(!json::accept("UndefIned"));
        CHECK(!json::accept("uNdefIned"));
        CHECK(!json::accept("UNdefIned"));
        CHECK(!json::accept("unDefIned"));
        CHECK(!json::accept("UnDefIned"));
        CHECK(!json::accept("uNDefIned"));
        CHECK(!json::accept("UNDefIned"));
        CHECK(!json::accept("undEfIned"));
        CHECK(!json::accept("UndEfIned"));
        CHECK(!json::accept("uNdEfIned"));
        CHECK(!json::accept("UNdEfIned"));
        CHECK(!json::accept("unDEfIned"));
        CHECK(!json::accept("UnDEfIned"));
        CHECK(!json::accept("uNDEfIned"));
        CHECK(!json::accept("UNDEfIned"));
        CHECK(!json::accept("undeFIned"));
        CHECK(!json::accept("UndeFIned"));
        CHECK(!json::accept("uNdeFIned"));
        CHECK(!json::accept("UNdeFIned"));
        CHECK(!json::accept("unDeFIned"));
        CHECK(!json::accept("UnDeFIned"));
        CHECK(!json::accept("uNDeFIned"));
        CHECK(!json::accept("UNDeFIned"));
        CHECK(!json::accept("undEFIned"));
        CHECK(!json::accept("UndEFIned"));
        CHECK(!json::accept("uNdEFIned"));
        CHECK(!json::accept("UNdEFIned"));
        CHECK(!json::accept("unDEFIned"));
        CHECK(!json::accept("UnDEFIned"));
        CHECK(!json::accept("uNDEFIned"));
        CHECK(!json::accept("UNDEFIned"));
        CHECK(!json::accept("undefiNed"));
        CHECK(!json::accept("UndefiNed"));
        CHECK(!json::accept("uNdefiNed"));
        CHECK(!json::accept("UNdefiNed"));
        CHECK(!json::accept("unDefiNed"));
        CHECK(!json::accept("UnDefiNed"));
        CHECK(!json::accept("uNDefiNed"));
        CHECK(!json::accept("UNDefiNed"));
        CHECK(!json::accept("undEfiNed"));
        CHECK(!json::accept("UndEfiNed"));
        CHECK(!json::accept("uNdEfiNed"));
        CHECK(!json::accept("UNdEfiNed"));
        CHECK(!json::accept("unDEfiNed"));
        CHECK(!json::accept("UnDEfiNed"));
        CHECK(!json::accept("uNDEfiNed"));
        CHECK(!json::accept("UNDEfiNed"));
        CHECK(!json::accept("undeFiNed"));
        CHECK(!json::accept("UndeFiNed"));
        CHECK(!json::accept("uNdeFiNed"));
        CHECK(!json::accept("UNdeFiNed"));
        CHECK(!json::accept("unDeFiNed"));
        CHECK(!json::accept("UnDeFiNed"));
        CHECK(!json::accept("uNDeFiNed"));
        CHECK(!json::accept("UNDeFiNed"));
        CHECK(!json::accept("undEFiNed"));
        CHECK(!json::accept("UndEFiNed"));
        CHECK(!json::accept("uNdEFiNed"));
        CHECK(!json::accept("UNdEFiNed"));
        CHECK(!json::accept("unDEFiNed"));
        CHECK(!json::accept("UnDEFiNed"));
        CHECK(!json::accept("uNDEFiNed"));
        CHECK(!json::accept("UNDEFiNed"));
        CHECK(!json::accept("undefINed"));
        CHECK(!json::accept("UndefINed"));
        CHECK(!json::accept("uNdefINed"));
        CHECK(!json::accept("UNdefINed"));
        CHECK(!json::accept("unDefINed"));
        CHECK(!json::accept("UnDefINed"));
        CHECK(!json::accept("uNDefINed"));
        CHECK(!json::accept("UNDefINed"));
        CHECK(!json::accept("undEfINed"));
        CHECK(!json::accept("UndEfINed"));
        CHECK(!json::accept("uNdEfINed"));
        CHECK(!json::accept("UNdEfINed"));
        CHECK(!json::accept("unDEfINed"));
        CHECK(!json::accept("UnDEfINed"));
        CHECK(!json::accept("uNDEfINed"));
        CHECK(!json::accept("UNDEfINed"));
        CHECK(!json::accept("undeFINed"));
        CHECK(!json::accept("UndeFINed"));
        CHECK(!json::accept("uNdeFINed"));
        CHECK(!json::accept("UNdeFINed"));
        CHECK(!json::accept("unDeFINed"));
        CHECK(!json::accept("UnDeFINed"));
        CHECK(!json::accept("uNDeFINed"));
        CHECK(!json::accept("UNDeFINed"));
        CHECK(!json::accept("undEFINed"));
        CHECK(!json::accept("UndEFINed"));
        CHECK(!json::accept("uNdEFINed"));
        CHECK(!json::accept("UNdEFINed"));
        CHECK(!json::accept("unDEFINed"));
        CHECK(!json::accept("UnDEFINed"));
        CHECK(!json::accept("uNDEFINed"));
        CHECK(!json::accept("UNDEFINed"));
        CHECK(!json::accept("undefinEd"));
        CHECK(!json::accept("UndefinEd"));
        CHECK(!json::accept("uNdefinEd"));
        CHECK(!json::accept("UNdefinEd"));
        CHECK(!json::accept("unDefinEd"));
        CHECK(!json::accept("UnDefinEd"));
        CHECK(!json::accept("uNDefinEd"));
        CHECK(!json::accept("UNDefinEd"));
        CHECK(!json::accept("undEfinEd"));
        CHECK(!json::accept("UndEfinEd"));
        CHECK(!json::accept("uNdEfinEd"));
        CHECK(!json::accept("UNdEfinEd"));
        CHECK(!json::accept("unDEfinEd"));
        CHECK(!json::accept("UnDEfinEd"));
        CHECK(!json::accept("uNDEfinEd"));
        CHECK(!json::accept("UNDEfinEd"));
        CHECK(!json::accept("undeFinEd"));
        CHECK(!json::accept("UndeFinEd"));
        CHECK(!json::accept("uNdeFinEd"));
        CHECK(!json::accept("UNdeFinEd"));
        CHECK(!json::accept("unDeFinEd"));
        CHECK(!json::accept("UnDeFinEd"));
        CHECK(!json::accept("uNDeFinEd"));
        CHECK(!json::accept("UNDeFinEd"));
        CHECK(!json::accept("undEFinEd"));
        CHECK(!json::accept("UndEFinEd"));
        CHECK(!json::accept("uNdEFinEd"));
        CHECK(!json::accept("UNdEFinEd"));
        CHECK(!json::accept("unDEFinEd"));
        CHECK(!json::accept("UnDEFinEd"));
        CHECK(!json::accept("uNDEFinEd"));
        CHECK(!json::accept("UNDEFinEd"));
        CHECK(!json::accept("undefInEd"));
        CHECK(!json::accept("UndefInEd"));
        CHECK(!json::accept("uNdefInEd"));
        CHECK(!json::accept("UNdefInEd"));
        CHECK(!json::accept("unDefInEd"));
        CHECK(!json::accept("UnDefInEd"));
        CHECK(!json::accept("uNDefInEd"));
        CHECK(!json::accept("UNDefInEd"));
        CHECK(!json::accept("undEfInEd"));
        CHECK(!json::accept("UndEfInEd"));
        CHECK(!json::accept("uNdEfInEd"));
        CHECK(!json::accept("UNdEfInEd"));
        CHECK(!json::accept("unDEfInEd"));
        CHECK(!json::accept("UnDEfInEd"));
        CHECK(!json::accept("uNDEfInEd"));
        CHECK(!json::accept("UNDEfInEd"));
        CHECK(!json::accept("undeFInEd"));
        CHECK(!json::accept("UndeFInEd"));
        CHECK(!json::accept("uNdeFInEd"));
        CHECK(!json::accept("UNdeFInEd"));
        CHECK(!json::accept("unDeFInEd"));
        CHECK(!json::accept("UnDeFInEd"));
        CHECK(!json::accept("uNDeFInEd"));
        CHECK(!json::accept("UNDeFInEd"));
        CHECK(!json::accept("undEFInEd"));
        CHECK(!json::accept("UndEFInEd"));
        CHECK(!json::accept("uNdEFInEd"));
        CHECK(!json::accept("UNdEFInEd"));
        CHECK(!json::accept("unDEFInEd"));
        CHECK(!json::accept("UnDEFInEd"));
        CHECK(!json::accept("uNDEFInEd"));
        CHECK(!json::accept("UNDEFInEd"));
        CHECK(!json::accept("undefiNEd"));
        CHECK(!json::accept("UndefiNEd"));
        CHECK(!json::accept("uNdefiNEd"));
        CHECK(!json::accept("UNdefiNEd"));
        CHECK(!json::accept("unDefiNEd"));
        CHECK(!json::accept("UnDefiNEd"));
        CHECK(!json::accept("uNDefiNEd"));
        CHECK(!json::accept("UNDefiNEd"));
        CHECK(!json::accept("undEfiNEd"));
        CHECK(!json::accept("UndEfiNEd"));
        CHECK(!json::accept("uNdEfiNEd"));
        CHECK(!json::accept("UNdEfiNEd"));
        CHECK(!json::accept("unDEfiNEd"));
        CHECK(!json::accept("UnDEfiNEd"));
        CHECK(!json::accept("uNDEfiNEd"));
        CHECK(!json::accept("UNDEfiNEd"));
        CHECK(!json::accept("undeFiNEd"));
        CHECK(!json::accept("UndeFiNEd"));
        CHECK(!json::accept("uNdeFiNEd"));
        CHECK(!json::accept("UNdeFiNEd"));
        CHECK(!json::accept("unDeFiNEd"));
        CHECK(!json::accept("UnDeFiNEd"));
        CHECK(!json::accept("uNDeFiNEd"));
        CHECK(!json::accept("UNDeFiNEd"));
        CHECK(!json::accept("undEFiNEd"));
        CHECK(!json::accept("UndEFiNEd"));
        CHECK(!json::accept("uNdEFiNEd"));
        CHECK(!json::accept("UNdEFiNEd"));
        CHECK(!json::accept("unDEFiNEd"));
        CHECK(!json::accept("UnDEFiNEd"));
        CHECK(!json::accept("uNDEFiNEd"));
        CHECK(!json::accept("UNDEFiNEd"));
        CHECK(!json::accept("undefINEd"));
        CHECK(!json::accept("UndefINEd"));
        CHECK(!json::accept("uNdefINEd"));
        CHECK(!json::accept("UNdefINEd"));
        CHECK(!json::accept("unDefINEd"));
        CHECK(!json::accept("UnDefINEd"));
        CHECK(!json::accept("uNDefINEd"));
        CHECK(!json::accept("UNDefINEd"));
        CHECK(!json::accept("undEfINEd"));
        CHECK(!json::accept("UndEfINEd"));
        CHECK(!json::accept("uNdEfINEd"));
        CHECK(!json::accept("UNdEfINEd"));
        CHECK(!json::accept("unDEfINEd"));
        CHECK(!json::accept("UnDEfINEd"));
        CHECK(!json::accept("uNDEfINEd"));
        CHECK(!json::accept("UNDEfINEd"));
        CHECK(!json::accept("undeFINEd"));
        CHECK(!json::accept("UndeFINEd"));
        CHECK(!json::accept("uNdeFINEd"));
        CHECK(!json::accept("UNdeFINEd"));
        CHECK(!json::accept("unDeFINEd"));
        CHECK(!json::accept("UnDeFINEd"));
        CHECK(!json::accept("uNDeFINEd"));
        CHECK(!json::accept("UNDeFINEd"));
        CHECK(!json::accept("undEFINEd"));
        CHECK(!json::accept("UndEFINEd"));
        CHECK(!json::accept("uNdEFINEd"));
        CHECK(!json::accept("UNdEFINEd"));
        CHECK(!json::accept("unDEFINEd"));
        CHECK(!json::accept("UnDEFINEd"));
        CHECK(!json::accept("uNDEFINEd"));
        CHECK(!json::accept("UNDEFINEd"));
        CHECK(!json::accept("undefineD"));
        CHECK(!json::accept("UndefineD"));
        CHECK(!json::accept("uNdefineD"));
        CHECK(!json::accept("UNdefineD"));
        CHECK(!json::accept("unDefineD"));
        CHECK(!json::accept("UnDefineD"));
        CHECK(!json::accept("uNDefineD"));
        CHECK(!json::accept("UNDefineD"));
        CHECK(!json::accept("undEfineD"));
        CHECK(!json::accept("UndEfineD"));
        CHECK(!json::accept("uNdEfineD"));
        CHECK(!json::accept("UNdEfineD"));
        CHECK(!json::accept("unDEfineD"));
        CHECK(!json::accept("UnDEfineD"));
        CHECK(!json::accept("uNDEfineD"));
        CHECK(!json::accept("UNDEfineD"));
        CHECK(!json::accept("undeFineD"));
        CHECK(!json::accept("UndeFineD"));
        CHECK(!json::accept("uNdeFineD"));
        CHECK(!json::accept("UNdeFineD"));
        CHECK(!json::accept("unDeFineD"));
        CHECK(!json::accept("UnDeFineD"));
        CHECK(!json::accept("uNDeFineD"));
        CHECK(!json::accept("UNDeFineD"));
        CHECK(!json::accept("undEFineD"));
        CHECK(!json::accept("UndEFineD"));
        CHECK(!json::accept("uNdEFineD"));
        CHECK(!json::accept("UNdEFineD"));
        CHECK(!json::accept("unDEFineD"));
        CHECK(!json::accept("UnDEFineD"));
        CHECK(!json::accept("uNDEFineD"));
        CHECK(!json::accept("UNDEFineD"));
        CHECK(!json::accept("undefIneD"));
        CHECK(!json::accept("UndefIneD"));
        CHECK(!json::accept("uNdefIneD"));
        CHECK(!json::accept("UNdefIneD"));
        CHECK(!json::accept("unDefIneD"));
        CHECK(!json::accept("UnDefIneD"));
        CHECK(!json::accept("uNDefIneD"));
        CHECK(!json::accept("UNDefIneD"));
        CHECK(!json::accept("undEfIneD"));
        CHECK(!json::accept("UndEfIneD"));
        CHECK(!json::accept("uNdEfIneD"));
        CHECK(!json::accept("UNdEfIneD"));
        CHECK(!json::accept("unDEfIneD"));
        CHECK(!json::accept("UnDEfIneD"));
        CHECK(!json::accept("uNDEfIneD"));
        CHECK(!json::accept("UNDEfIneD"));
        CHECK(!json::accept("undeFIneD"));
        CHECK(!json::accept("UndeFIneD"));
        CHECK(!json::accept("uNdeFIneD"));
        CHECK(!json::accept("UNdeFIneD"));
        CHECK(!json::accept("unDeFIneD"));
        CHECK(!json::accept("UnDeFIneD"));
        CHECK(!json::accept("uNDeFIneD"));
        CHECK(!json::accept("UNDeFIneD"));
        CHECK(!json::accept("undEFIneD"));
        CHECK(!json::accept("UndEFIneD"));
        CHECK(!json::accept("uNdEFIneD"));
        CHECK(!json::accept("UNdEFIneD"));
        CHECK(!json::accept("unDEFIneD"));
        CHECK(!json::accept("UnDEFIneD"));
        CHECK(!json::accept("uNDEFIneD"));
        CHECK(!json::accept("UNDEFIneD"));
        CHECK(!json::accept("undefiNeD"));
        CHECK(!json::accept("UndefiNeD"));
        CHECK(!json::accept("uNdefiNeD"));
        CHECK(!json::accept("UNdefiNeD"));
        CHECK(!json::accept("unDefiNeD"));
        CHECK(!json::accept("UnDefiNeD"));
        CHECK(!json::accept("uNDefiNeD"));
        CHECK(!json::accept("UNDefiNeD"));
        CHECK(!json::accept("undEfiNeD"));
        CHECK(!json::accept("UndEfiNeD"));
        CHECK(!json::accept("uNdEfiNeD"));
        CHECK(!json::accept("UNdEfiNeD"));
        CHECK(!json::accept("unDEfiNeD"));
        CHECK(!json::accept("UnDEfiNeD"));
        CHECK(!json::accept("uNDEfiNeD"));
        CHECK(!json::accept("UNDEfiNeD"));
        CHECK(!json::accept("undeFiNeD"));
        CHECK(!json::accept("UndeFiNeD"));
        CHECK(!json::accept("uNdeFiNeD"));
        CHECK(!json::accept("UNdeFiNeD"));
        CHECK(!json::accept("unDeFiNeD"));
        CHECK(!json::accept("UnDeFiNeD"));
        CHECK(!json::accept("uNDeFiNeD"));
        CHECK(!json::accept("UNDeFiNeD"));
        CHECK(!json::accept("undEFiNeD"));
        CHECK(!json::accept("UndEFiNeD"));
        CHECK(!json::accept("uNdEFiNeD"));
        CHECK(!json::accept("UNdEFiNeD"));
        CHECK(!json::accept("unDEFiNeD"));
        CHECK(!json::accept("UnDEFiNeD"));
        CHECK(!json::accept("uNDEFiNeD"));
        CHECK(!json::accept("UNDEFiNeD"));
        CHECK(!json::accept("undefINeD"));
        CHECK(!json::accept("UndefINeD"));
        CHECK(!json::accept("uNdefINeD"));
        CHECK(!json::accept("UNdefINeD"));
        CHECK(!json::accept("unDefINeD"));
        CHECK(!json::accept("UnDefINeD"));
        CHECK(!json::accept("uNDefINeD"));
        CHECK(!json::accept("UNDefINeD"));
        CHECK(!json::accept("undEfINeD"));
        CHECK(!json::accept("UndEfINeD"));
        CHECK(!json::accept("uNdEfINeD"));
        CHECK(!json::accept("UNdEfINeD"));
        CHECK(!json::accept("unDEfINeD"));
        CHECK(!json::accept("UnDEfINeD"));
        CHECK(!json::accept("uNDEfINeD"));
        CHECK(!json::accept("UNDEfINeD"));
        CHECK(!json::accept("undeFINeD"));
        CHECK(!json::accept("UndeFINeD"));
        CHECK(!json::accept("uNdeFINeD"));
        CHECK(!json::accept("UNdeFINeD"));
        CHECK(!json::accept("unDeFINeD"));
        CHECK(!json::accept("UnDeFINeD"));
        CHECK(!json::accept("uNDeFINeD"));
        CHECK(!json::accept("UNDeFINeD"));
        CHECK(!json::accept("undEFINeD"));
        CHECK(!json::accept("UndEFINeD"));
        CHECK(!json::accept("uNdEFINeD"));
        CHECK(!json::accept("UNdEFINeD"));
        CHECK(!json::accept("unDEFINeD"));
        CHECK(!json::accept("UnDEFINeD"));
        CHECK(!json::accept("uNDEFINeD"));
        CHECK(!json::accept("UNDEFINeD"));
        CHECK(!json::accept("undefinED"));
        CHECK(!json::accept("UndefinED"));
        CHECK(!json::accept("uNdefinED"));
        CHECK(!json::accept("UNdefinED"));
        CHECK(!json::accept("unDefinED"));
        CHECK(!json::accept("UnDefinED"));
        CHECK(!json::accept("uNDefinED"));
        CHECK(!json::accept("UNDefinED"));
        CHECK(!json::accept("undEfinED"));
        CHECK(!json::accept("UndEfinED"));
        CHECK(!json::accept("uNdEfinED"));
        CHECK(!json::accept("UNdEfinED"));
        CHECK(!json::accept("unDEfinED"));
        CHECK(!json::accept("UnDEfinED"));
        CHECK(!json::accept("uNDEfinED"));
        CHECK(!json::accept("UNDEfinED"));
        CHECK(!json::accept("undeFinED"));
        CHECK(!json::accept("UndeFinED"));
        CHECK(!json::accept("uNdeFinED"));
        CHECK(!json::accept("UNdeFinED"));
        CHECK(!json::accept("unDeFinED"));
        CHECK(!json::accept("UnDeFinED"));
        CHECK(!json::accept("uNDeFinED"));
        CHECK(!json::accept("UNDeFinED"));
        CHECK(!json::accept("undEFinED"));
        CHECK(!json::accept("UndEFinED"));
        CHECK(!json::accept("uNdEFinED"));
        CHECK(!json::accept("UNdEFinED"));
        CHECK(!json::accept("unDEFinED"));
        CHECK(!json::accept("UnDEFinED"));
        CHECK(!json::accept("uNDEFinED"));
        CHECK(!json::accept("UNDEFinED"));
        CHECK(!json::accept("undefInED"));
        CHECK(!json::accept("UndefInED"));
        CHECK(!json::accept("uNdefInED"));
        CHECK(!json::accept("UNdefInED"));
        CHECK(!json::accept("unDefInED"));
        CHECK(!json::accept("UnDefInED"));
        CHECK(!json::accept("uNDefInED"));
        CHECK(!json::accept("UNDefInED"));
        CHECK(!json::accept("undEfInED"));
        CHECK(!json::accept("UndEfInED"));
        CHECK(!json::accept("uNdEfInED"));
        CHECK(!json::accept("UNdEfInED"));
        CHECK(!json::accept("unDEfInED"));
        CHECK(!json::accept("UnDEfInED"));
        CHECK(!json::accept("uNDEfInED"));
        CHECK(!json::accept("UNDEfInED"));
        CHECK(!json::accept("undeFInED"));
        CHECK(!json::accept("UndeFInED"));
        CHECK(!json::accept("uNdeFInED"));
        CHECK(!json::accept("UNdeFInED"));
        CHECK(!json::accept("unDeFInED"));
        CHECK(!json::accept("UnDeFInED"));
        CHECK(!json::accept("uNDeFInED"));
        CHECK(!json::accept("UNDeFInED"));
        CHECK(!json::accept("undEFInED"));
        CHECK(!json::accept("UndEFInED"));
        CHECK(!json::accept("uNdEFInED"));
        CHECK(!json::accept("UNdEFInED"));
        CHECK(!json::accept("unDEFInED"));
        CHECK(!json::accept("UnDEFInED"));
        CHECK(!json::accept("uNDEFInED"));
        CHECK(!json::accept("UNDEFInED"));
        CHECK(!json::accept("undefiNED"));
        CHECK(!json::accept("UndefiNED"));
        CHECK(!json::accept("uNdefiNED"));
        CHECK(!json::accept("UNdefiNED"));
        CHECK(!json::accept("unDefiNED"));
        CHECK(!json::accept("UnDefiNED"));
        CHECK(!json::accept("uNDefiNED"));
        CHECK(!json::accept("UNDefiNED"));
        CHECK(!json::accept("undEfiNED"));
        CHECK(!json::accept("UndEfiNED"));
        CHECK(!json::accept("uNdEfiNED"));
        CHECK(!json::accept("UNdEfiNED"));
        CHECK(!json::accept("unDEfiNED"));
        CHECK(!json::accept("UnDEfiNED"));
        CHECK(!json::accept("uNDEfiNED"));
        CHECK(!json::accept("UNDEfiNED"));
        CHECK(!json::accept("undeFiNED"));
        CHECK(!json::accept("UndeFiNED"));
        CHECK(!json::accept("uNdeFiNED"));
        CHECK(!json::accept("UNdeFiNED"));
        CHECK(!json::accept("unDeFiNED"));
        CHECK(!json::accept("UnDeFiNED"));
        CHECK(!json::accept("uNDeFiNED"));
        CHECK(!json::accept("UNDeFiNED"));
        CHECK(!json::accept("undEFiNED"));
        CHECK(!json::accept("UndEFiNED"));
        CHECK(!json::accept("uNdEFiNED"));
        CHECK(!json::accept("UNdEFiNED"));
        CHECK(!json::accept("unDEFiNED"));
        CHECK(!json::accept("UnDEFiNED"));
        CHECK(!json::accept("uNDEFiNED"));
        CHECK(!json::accept("UNDEFiNED"));
        CHECK(!json::accept("undefINED"));
        CHECK(!json::accept("UndefINED"));
        CHECK(!json::accept("uNdefINED"));
        CHECK(!json::accept("UNdefINED"));
        CHECK(!json::accept("unDefINED"));
        CHECK(!json::accept("UnDefINED"));
        CHECK(!json::accept("uNDefINED"));
        CHECK(!json::accept("UNDefINED"));
        CHECK(!json::accept("undEfINED"));
        CHECK(!json::accept("UndEfINED"));
        CHECK(!json::accept("uNdEfINED"));
        CHECK(!json::accept("UNdEfINED"));
        CHECK(!json::accept("unDEfINED"));
        CHECK(!json::accept("UnDEfINED"));
        CHECK(!json::accept("uNDEfINED"));
        CHECK(!json::accept("UNDEfINED"));
        CHECK(!json::accept("undeFINED"));
        CHECK(!json::accept("UndeFINED"));
        CHECK(!json::accept("uNdeFINED"));
        CHECK(!json::accept("UNdeFINED"));
        CHECK(!json::accept("unDeFINED"));
        CHECK(!json::accept("UnDeFINED"));
        CHECK(!json::accept("uNDeFINED"));
        CHECK(!json::accept("UNDeFINED"));
        CHECK(!json::accept("undEFINED"));
        CHECK(!json::accept("UndEFINED"));
        CHECK(!json::accept("uNdEFINED"));
        CHECK(!json::accept("UNdEFINED"));
        CHECK(!json::accept("unDEFINED"));
        CHECK(!json::accept("UnDEFINED"));
        CHECK(!json::accept("uNDEFINED"));
        CHECK(!json::accept("UNDEFINED"));
    }
}
  • function: [lexer::scan_literal] (include/nlohmann/detail/input/lexer.hpp)

    • Description: function to verify whether a candidate literal coincides with its expected value; only ever called with the three admissible expected values

token_type scan_literal(const char_type* literal_text, const std::size_t length,
                        token_type return_type)
{
    JSON_ASSERT(char_traits<char_type>::to_char_type(current) == literal_text[0]);
    for (std::size_t i = 1; i < length; ++i)
    {
        if (JSON_HEDLEY_UNLIKELY(char_traits<char_type>::to_char_type(get()) != literal_text[i]))
        {
            error_message = "invalid literal";
            return token_type::parse_error;
        }
    }
    return return_type;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-05#

The service accepts and rejects arrays according to RFC8259 §5.

Supported Requests:

Supporting Items:

References:

None

Fallacies:

None

Graph:

No Historic Data Found


NJF-05.1#

The service accepts the empty array.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;array;empty array] (TSF/tests/unit-class_parser_core.cpp)

SECTION("empty array")
{
    CHECK(accept_helper("[]"));
    CHECK(accept_helper("[ ]"));
}
  • cpp-testsuite: [/nst_json_testsuite/test_parsing/y_array_empty.json]

    • JSON Testsuite: /nst_json_testsuite/test_parsing/y_array_empty.json

    []
    
    • cpp-test: [nst’s JSONTestSuite;test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/y_array_empty.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json j;
            CHECK_NOTHROW(f >> j);
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_array_empty.json, /nst_json_testsuite2/test_parsing/y_array_arraysWithSpaces.json]

    • Description: Checks that the empty array [] is accepted.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_array_empty.json

    []
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_array_arraysWithSpaces.json

    [[]   ]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_arraysWithSpaces.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_empty.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • function: [lexer::skip_whitespace] (include/nlohmann/detail/input/lexer.hpp)

    • Description: function, which skips admissible whitespace during reading

void skip_whitespace()
{
    do
    {
        get();
    }
    while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-05.2#

The service accepts the non-empty arrays.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;array;nonempty array] (TSF/tests/unit-class_parser_core.cpp)

SECTION("nonempty array")
{
    CHECK(accept_helper("[true, false, null]"));
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_array_false.json, /nst_json_testsuite2/test_parsing/y_array_heterogeneous.json, /nst_json_testsuite2/test_parsing/y_array_null.json, /nst_json_testsuite2/test_parsing/y_array_with_1_and_newline.json, /nst_json_testsuite2/test_parsing/y_array_with_leading_space.json, /nst_json_testsuite2/test_parsing/y_array_with_several_null.json, /nst_json_testsuite2/test_parsing/y_array_with_trailing_space.json]

    • Description: Checks that various valid arrays are accepted.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_array_false.json

    [false]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_array_heterogeneous.json

    [null, 1, "1", {}]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_array_null.json

    [null]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_array_with_1_and_newline.json

    [1
    ]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_array_with_leading_space.json

    [1]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_array_with_several_null.json

    [1,null,null,null,2]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_array_with_trailing_space.json

    [2] 
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_false.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_heterogeneous.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_null.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_with_1_and_newline.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_with_leading_space.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_with_several_null.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_with_trailing_space.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/json.org/1.json, /json.org/2.json, /json.org/3.json, /json.org/4.json, /json.org/5.json]

    • Description: Checks that various valid arrays in combination with objects are accepted.

    • JSON Testsuite: /json.org/1.json

    {
       "glossary": {
           "title": "example glossary",
       	"GlossDiv": {
               "title": "S",
       		"GlossList": {
                   "GlossEntry": {
                       "ID": "SGML",
       				"SortAs": "SGML",
       				"GlossTerm": "Standard Generalized Markup Language",
       				"Acronym": "SGML",
       				"Abbrev": "ISO 8879:1986",
       				"GlossDef": {
                           "para": "A meta-markup language, used to create markup languages such as DocBook.",
       					"GlossSeeAlso": ["GML", "XML"]
                       },
       				"GlossSee": "markup"
                   }
               }
           }
       }
    }
    
    • JSON Testsuite: /json.org/2.json

    {"menu": {
     "id": "file",
     "value": "File",
     "popup": {
       "menuitem": [
         {"value": "New", "onclick": "CreateNewDoc()"},
         {"value": "Open", "onclick": "OpenDoc()"},
         {"value": "Close", "onclick": "CloseDoc()"}
       ]
     }
    }}
    
    • JSON Testsuite: /json.org/3.json

    Link to file [Content too large - 26 lines]

    • JSON Testsuite: /json.org/4.json

    Link to file [Content too large - 88 lines]

    • JSON Testsuite: /json.org/5.json

    Link to file [Content too large - 27 lines]

    • cpp-test: [json.org examples] (tests/src/unit-testsuites.cpp)

    TEST_CASE("json.org examples")
    {
        // here, we list all JSON values from https://json.org/example
        using FilePtr = std::unique_ptr<FILE, int(*)(FILE*)>;
    
        SECTION("1.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/1.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("2.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/2.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("3.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/3.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("4.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/4.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("5.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/5.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
        SECTION("FILE 1.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/1.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 2.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/2.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 3.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/3.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 4.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/4.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 5.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/5.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    }
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-05.3#

If every value candidate of a properly bounded array is accepted as singleton, then the service accepts the array.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [deserialization;successful deserialization;stream] (tests/src/unit-deserialization.cpp)

SECTION("stream")
{
    std::stringstream ss1;
    std::stringstream ss2;
    std::stringstream ss3;
    ss1 << R"(["foo",1,2,3,false,{"one":1}])";
    ss2 << R"(["foo",1,2,3,false,{"one":1}])";
    ss3 << R"(["foo",1,2,3,false,{"one":1}])";
    json j = json::parse(ss1);
    CHECK(json::accept(ss2));
    CHECK(j == json({"foo", 1, 2, 3, false, {{"one", 1}}}));

    SaxEventLogger l;
    CHECK(json::sax_parse(ss3, &l));
    CHECK(l.events.size() == 11);
    CHECK(l.events == std::vector<std::string>(
    {
        "start_array()", "string(foo)", "number_unsigned(1)",
        "number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
        "start_object()", "key(one)", "number_unsigned(1)",
        "end_object()", "end_array()"
    }));
}
  • cpp-testsuite: [/json.org/1.json, /json.org/2.json, /json.org/3.json, /json.org/4.json, /json.org/5.json]

    • Description: Checks that various valid arrays in combination with objects are accepted.

    • JSON Testsuite: /json.org/1.json

    {
       "glossary": {
           "title": "example glossary",
       	"GlossDiv": {
               "title": "S",
       		"GlossList": {
                   "GlossEntry": {
                       "ID": "SGML",
       				"SortAs": "SGML",
       				"GlossTerm": "Standard Generalized Markup Language",
       				"Acronym": "SGML",
       				"Abbrev": "ISO 8879:1986",
       				"GlossDef": {
                           "para": "A meta-markup language, used to create markup languages such as DocBook.",
       					"GlossSeeAlso": ["GML", "XML"]
                       },
       				"GlossSee": "markup"
                   }
               }
           }
       }
    }
    
    • JSON Testsuite: /json.org/2.json

    {"menu": {
     "id": "file",
     "value": "File",
     "popup": {
       "menuitem": [
         {"value": "New", "onclick": "CreateNewDoc()"},
         {"value": "Open", "onclick": "OpenDoc()"},
         {"value": "Close", "onclick": "CloseDoc()"}
       ]
     }
    }}
    
    • JSON Testsuite: /json.org/3.json

    Link to file [Content too large - 26 lines]

    • JSON Testsuite: /json.org/4.json

    Link to file [Content too large - 88 lines]

    • JSON Testsuite: /json.org/5.json

    Link to file [Content too large - 27 lines]

    • cpp-test: [json.org examples] (tests/src/unit-testsuites.cpp)

    TEST_CASE("json.org examples")
    {
        // here, we list all JSON values from https://json.org/example
        using FilePtr = std::unique_ptr<FILE, int(*)(FILE*)>;
    
        SECTION("1.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/1.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("2.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/2.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("3.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/3.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("4.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/4.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("5.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/5.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
        SECTION("FILE 1.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/1.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 2.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/2.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 3.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/3.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 4.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/4.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 5.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/5.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    }
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_string_in_array.json, /nst_json_testsuite2/test_parsing/y_string_in_array_with_leading_space.json, /nst_json_testsuite2/test_parsing/y_structure_true_in_array.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_in_array.json

    ["asd"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_in_array_with_leading_space.json

    [ "asd"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_structure_true_in_array.json

    [true]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_in_array.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_in_array_with_leading_space.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_true_in_array.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-05.4#

The service does not accept any improperly bounded arrays.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;parse errors (accept)] (TSF/tests/unit-class_parser_core.cpp)

SECTION("parse errors (accept)")
{
    // unexpected end of number
    CHECK(accept_helper("0.") == false);
    CHECK(accept_helper("-") == false);
    CHECK(accept_helper("--") == false);
    CHECK(accept_helper("-0.") == false);
    CHECK(accept_helper("-.") == false);
    CHECK(accept_helper("-:") == false);
    CHECK(accept_helper("0.:") == false);
    CHECK(accept_helper("e.") == false);
    CHECK(accept_helper("1e.") == false);
    CHECK(accept_helper("1e/") == false);
    CHECK(accept_helper("1e:") == false);
    CHECK(accept_helper("1E.") == false);
    CHECK(accept_helper("1E/") == false);
    CHECK(accept_helper("1E:") == false);

    // unexpected end of null
    CHECK(accept_helper("n") == false);
    CHECK(accept_helper("nu") == false);
    CHECK(accept_helper("nul") == false);

    // unexpected end of true
    CHECK(accept_helper("t") == false);
    CHECK(accept_helper("tr") == false);
    CHECK(accept_helper("tru") == false);

    // unexpected end of false
    CHECK(accept_helper("f") == false);
    CHECK(accept_helper("fa") == false);
    CHECK(accept_helper("fal") == false);
    CHECK(accept_helper("fals") == false);

    // missing/unexpected end of array
    CHECK(accept_helper("[") == false);
    CHECK(accept_helper("[1") == false);
    CHECK(accept_helper("[1,") == false);
    CHECK(accept_helper("[1,]") == false);
    CHECK(accept_helper("]") == false);

    // missing/unexpected end of object
    CHECK(accept_helper("{") == false);
    CHECK(accept_helper("{\"foo\"") == false);
    CHECK(accept_helper("{\"foo\":") == false);
    CHECK(accept_helper("{\"foo\":}") == false);
    CHECK(accept_helper("{\"foo\":1,}") == false);
    CHECK(accept_helper("}") == false);

    // missing/unexpected end of string
    CHECK(accept_helper("\"") == false);
    CHECK(accept_helper("\"\\\"") == false);
    CHECK(accept_helper("\"\\u\"") == false);
    CHECK(accept_helper("\"\\u0\"") == false);
    CHECK(accept_helper("\"\\u01\"") == false);
    CHECK(accept_helper("\"\\u012\"") == false);
    CHECK(accept_helper("\"\\u") == false);
    CHECK(accept_helper("\"\\u0") == false);
    CHECK(accept_helper("\"\\u01") == false);
    CHECK(accept_helper("\"\\u012") == false);

    // unget of newline
    CHECK(parser_helper("\n123\n") == 123);

    // invalid escapes
    for (int c = 1; c < 128; ++c)
    {
        auto s = std::string("\"\\") + std::string(1, static_cast<char>(c)) + "\"";

        switch (c)
        {
            // valid escapes
            case ('"'):
            case ('\\'):
            case ('/'):
            case ('b'):
            case ('f'):
            case ('n'):
            case ('r'):
            case ('t'):
            {
                CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept());
                break;
            }

            // \u must be followed with four numbers, so we skip it here
            case ('u'):
            {
                break;
            }

            // any other combination of backslash and character is invalid
            default:
            {
                CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept() == false);
                break;
            }
        }
    }

    // invalid \uxxxx escapes
    {
        // check whether character is a valid hex character
        const auto valid = [](int c)
        {
            switch (c)
            {
                case ('0'):
                case ('1'):
                case ('2'):
                case ('3'):
                case ('4'):
                case ('5'):
                case ('6'):
                case ('7'):
                case ('8'):
                case ('9'):
                case ('a'):
                case ('b'):
                case ('c'):
                case ('d'):
                case ('e'):
                case ('f'):
                case ('A'):
                case ('B'):
                case ('C'):
                case ('D'):
                case ('E'):
                case ('F'):
                {
                    return true;
                }

                default:
                {
                    return false;
                }
            }
        };

        for (int c = 1; c < 128; ++c)
        {
            std::string const s = "\"\\u";

            // create a string with the iterated character at each position
            const auto s1 = s + "000" + std::string(1, static_cast<char>(c)) + "\"";
            const auto s2 = s + "00" + std::string(1, static_cast<char>(c)) + "0\"";
            const auto s3 = s + "0" + std::string(1, static_cast<char>(c)) + "00\"";
            const auto s4 = s + std::string(1, static_cast<char>(c)) + "000\"";

            if (valid(c))
            {
                CAPTURE(s1)
                CHECK(json::parser(nlohmann::detail::input_adapter(s1)).accept());
                CAPTURE(s2)
                CHECK(json::parser(nlohmann::detail::input_adapter(s2)).accept());
                CAPTURE(s3)
                CHECK(json::parser(nlohmann::detail::input_adapter(s3)).accept());
                CAPTURE(s4)
                CHECK(json::parser(nlohmann::detail::input_adapter(s4)).accept());
            }
            else
            {
                CAPTURE(s1)
                CHECK(json::parser(nlohmann::detail::input_adapter(s1)).accept() == false);

                CAPTURE(s2)
                CHECK(json::parser(nlohmann::detail::input_adapter(s2)).accept() == false);

                CAPTURE(s3)
                CHECK(json::parser(nlohmann::detail::input_adapter(s3)).accept() == false);

                CAPTURE(s4)
                CHECK(json::parser(nlohmann::detail::input_adapter(s4)).accept() == false);
            }
        }
    }

    // missing part of a surrogate pair
    CHECK(accept_helper("\"\\uD80C\"") == false);
    // invalid surrogate pair
    CHECK(accept_helper("\"\\uD80C\\uD80C\"") == false);
    CHECK(accept_helper("\"\\uD80C\\u0000\"") == false);
    CHECK(accept_helper("\"\\uD80C\\uFFFF\"") == false);
}
  • cpp-test: [accept;boundaries] (TSF/tests/unit-arrays.cpp)

SECTION("boundaries")
{
    CHECK(!json::accept("[}"));
    CHECK(!json::accept("[\"foobar\"}"));
    CHECK(!json::accept("[1.23\u004513}"));
    CHECK(!json::accept("[[1,32,5,\"foo\"]}"));
    CHECK(!json::accept("{]"));
    CHECK(!json::accept("{\"foobar\"]"));
    CHECK(!json::accept("{1.23\u004513]"));
    CHECK(!json::accept("{[1,32,5,\"foo\"]]"));
    CHECK(!json::accept("(]"));
    CHECK(!json::accept("(\"foobar\"]"));
    CHECK(!json::accept("(1.23\u004513]"));
    CHECK(!json::accept("([1,32,5,\"foo\"]]"));

    // Test whether 100,000 opening brackets with "Moin!" and 99,999 closing brackets are rejected.
    std::stringstream faulty_array;
    for (int i = 0; i < 100000; i++){
        faulty_array << "[";
    }
    faulty_array << "\"Moin!\"";
    for (int i = 1; i < 100000; i++){
        faulty_array << "]";
    }
    CHECK(!json::accept(faulty_array.str()));
    // double check if rejection is not due to overflow
    CHECK_THROWS_AS(parser_helper(faulty_array.str()),json::parse_error&);
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_structure_100000_opening_arrays.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_100000_opening_arrays.json

    [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n (previously overflowed)] (tests/src/unit-testsuites.cpp)

    SECTION("n (previously overflowed)")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_100000_opening_arrays.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            CHECK(!json::accept(f));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_structure_close_unopened_array.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_close_unopened_array.json

    1]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_close_unopened_array.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_structure_double_array.json, /nst_json_testsuite2/test_parsing/n_structure_end_array.json, /nst_json_testsuite2/test_parsing/n_structure_lone-invalid-utf-8.json, /nst_json_testsuite2/test_parsing/n_structure_open_array_apostrophe.json, /nst_json_testsuite2/test_parsing/n_structure_open_array_comma.json, /nst_json_testsuite2/test_parsing/n_structure_open_array_open_object.json, /nst_json_testsuite2/test_parsing/n_structure_open_object_close_array.json, /nst_json_testsuite2/test_parsing/n_structure_unclosed_array.json, /nst_json_testsuite2/test_parsing/n_structure_unclosed_array_partial_null.json, /nst_json_testsuite2/test_parsing/n_structure_unclosed_array_unfinished_false.json, /nst_json_testsuite2/test_parsing/n_structure_unclosed_array_unfinished_true.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_double_array.json

    [][]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_end_array.json

    ]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_lone-invalid-utf-8.json

    V
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_open_array_apostrophe.json

    ['
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_open_array_comma.json

    [,
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_open_array_open_object.json

    [{
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_open_object_close_array.json

    {]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_unclosed_array.json

    [1
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_unclosed_array_partial_null.json

    [ false, nul
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_unclosed_array_unfinished_false.json

    [ true, fals
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_unclosed_array_unfinished_true.json

    [ false, tru
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_double_array.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_end_array.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_lone-invalid-utf-8.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_array_apostrophe.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_array_comma.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_array_open_object.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_object_close_array.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_array.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_array_partial_null.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_array_unfinished_false.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_array_unfinished_true.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-05.5#

The service does not accept arrays with improper values.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_array_double_comma.json, /nst_json_testsuite2/test_parsing/n_array_double_extra_comma.json, /nst_json_testsuite2/test_parsing/n_array_just_comma.json, /nst_json_testsuite2/test_parsing/n_array_number_and_comma.json, /nst_json_testsuite2/test_parsing/n_array_number_and_several_commas.json, /nst_json_testsuite2/test_parsing/n_structure_array_with_unclosed_string.json, /nst_json_testsuite2/test_parsing/n_array_invalid_utf8.json, /nst_json_testsuite2/test_parsing/n_array_just_minus.json]

    • Description: Checks that various “proper” arrays with improper elements are rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_array_double_comma.json

    [1,,2]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_array_double_extra_comma.json

    ["x",,]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_array_just_comma.json

    [,]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_array_number_and_comma.json

    [1,]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_array_number_and_several_commas.json

    [1,,]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_array_with_unclosed_string.json

    ["asd]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_array_invalid_utf8.json

    []
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_array_just_minus.json

    [-]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_double_comma.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_double_extra_comma.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_invalid_utf8.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_just_comma.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_just_minus.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_number_and_comma.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_number_and_several_commas.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_array_with_unclosed_string.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-05.6#

The service accepts nested arrays.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/json_tests/pass2.json]

    • JSON Testsuite: /json_tests/pass2.json

    [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
    
    • cpp-test: [compliance tests from json.org;expected passes] (tests/src/unit-testsuites.cpp)

    SECTION("expected passes")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/json_tests/pass2.json",
                })
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json j;
            CHECK_NOTHROW(f >> j);
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json

    [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;i -> y] (tests/src/unit-testsuites.cpp)

    SECTION("i -> y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-05.6.0#

The acceptance of nested arrays does not depend on the depth of nesting.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json

    [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;i -> y] (tests/src/unit-testsuites.cpp)

    SECTION("i -> y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_structure_500_nested_arrays.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-05.7#

The service does only accept comma as value separator.

Supported Requests:

Supporting Items:

References:

None

Fallacies:

None

Graph:

No Historic Data Found


NJF-05.7.1#

The service does accept comma as value separator.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_array_with_several_null.json]

    • Description: Checks that [1,null,null,null,2] is accepted.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_array_with_several_null.json

    [1,null,null,null,2]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_array_with_several_null.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/json.org/4.json]

    • JSON Testsuite: /json.org/4.json

    Link to file [Content too large - 88 lines]

    • cpp-test: [json.org examples;4.json] (tests/src/unit-testsuites.cpp)

    SECTION("4.json")
    {
        std::ifstream f(TEST_DATA_DIRECTORY "/json.org/4.json");
        json j;
        CHECK_NOTHROW(f >> j);
    }
    
  • cpp-testsuite: [/json.org/5.json]

    • JSON Testsuite: /json.org/5.json

    Link to file [Content too large - 27 lines]

    • cpp-test: [json.org examples;5.json] (tests/src/unit-testsuites.cpp)

    SECTION("5.json")
    {
        std::ifstream f(TEST_DATA_DIRECTORY "/json.org/5.json");
        json j;
        CHECK_NOTHROW(f >> j);
    }
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-05.7.2#

The service does not accept any other value separator.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_array_colon_instead_of_comma.json]

    • Description: Tests whether colon as value separator is rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_array_colon_instead_of_comma.json

    ["": 1]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_colon_instead_of_comma.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-06#

The service accepts and rejects objects according to RFC8259 §4.

Supported Requests:

Supporting Items:

References:

None

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.1#

The service accepts the empty object.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;object;empty object] (TSF/tests/unit-class_parser_core.cpp)

SECTION("empty object")
{
    CHECK(accept_helper("{}"));
    CHECK(accept_helper("{ }"));
}
  • cpp-test: [accept;whitespace;empty object] (TSF/tests/unit-objects.cpp)

SECTION("empty object")
{
    CHECK(json::accept("{          }"));
    CHECK(json::accept("{\t}"));
    CHECK(json::accept("{\n}"));
    CHECK(json::accept("{\u000d}"));
    CHECK(json::accept("{\u000d\u000d\u000d  \t\t\t\n\n   \u000d \n\t  \t \u000d}"));
}
  • function: [lexer::skip_whitespace] (include/nlohmann/detail/input/lexer.hpp)

    • Description: function, which skips admissible whitespace during reading

void skip_whitespace()
{
    do
    {
        get();
    }
    while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.2#

The service does not accept improperly bounded objects.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [deserialization;contiguous containers;error cases;case 15] (tests/src/unit-deserialization.cpp)

SECTION("case 15")
{
    std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF4, 0x7F}};
    json _;
    CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
    CHECK(!json::accept(std::begin(v), std::end(v)));

    json j_error;
    CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
    CHECK(j_error.is_discarded());

    SaxEventLogger l;
    CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
    CHECK(l.events.size() == 1);
    CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_structure_comma_instead_of_closing_brace.json, /nst_json_testsuite2/test_parsing/n_structure_object_followed_by_closing_object.json, /nst_json_testsuite2/test_parsing/n_structure_object_unclosed_no_value.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_comma_instead_of_closing_brace.json

    {"x": true,
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_object_followed_by_closing_object.json

    {}}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_object_unclosed_no_value.json

    {"":
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_comma_instead_of_closing_brace.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_object_followed_by_closing_object.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_object_unclosed_no_value.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.3#

The service accepts the non-empty objects.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [deserialization;JSON Lines] (tests/src/unit-deserialization.cpp)

    SECTION("JSON Lines")
    {
        SECTION("Example file")
        {
            std::stringstream ss;
            ss << R"({"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
                    {"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
                    {"name": "May", "wins": []}
                    {"name": "Deloise", "wins": [["three of a kind", "5♣"]]}
)";

            std::string line;
            int object_count = 0;
            while (std::getline(ss, line))
            {
                ++object_count;
                CHECK(json::accept(line));
            }

            CHECK(object_count == 4);
        }

        SECTION("Example file without trailing newline")
        {
            std::stringstream ss;
            ss << R"({"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
                    {"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
                    {"name": "May", "wins": []}
                    {"name": "Deloise", "wins": [["three of a kind", "5♣"]]})";

            std::string line;
            int object_count = 0;
            while (std::getline(ss, line))
            {
                ++object_count;
                CHECK(json::accept(line));
            }

            CHECK(object_count == 4);
        }
    }
  • cpp-test: [parser class - core;accept;object;nonempty object] (TSF/tests/unit-class_parser_core.cpp)

SECTION("nonempty object")
{
    CHECK(accept_helper("{\"\": true, \"one\": 1, \"two\": null}"));
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.4#

The admissible members of an object have the form name : value.

Supported Requests:

Supporting Items:

References:

  • cpp-test: [nst's JSONTestSuite;test_parsing;n] (tests/src/unit-testsuites.cpp)

SECTION("n")
{
    for (const auto* filename :
            {
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_1_true_without_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_a_invalid_utf8.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_colon_instead_of_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_comma_after_close.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_comma_and_number.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_double_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_double_extra_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_extra_close.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_extra_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_incomplete.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_incomplete_invalid_value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_inner_array_no_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_invalid_utf8.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_items_separated_by_semicolon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_just_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_just_minus.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_missing_value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_newlines_unclosed.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_number_and_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_number_and_several_commas.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_spaces_vertical_tab_formfeed.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_star_inside.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_unclosed.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_unclosed_trailing_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_unclosed_with_new_lines.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_array_unclosed_with_object_inside.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_incomplete_false.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_incomplete_null.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_incomplete_true.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_++.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_+1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_+Inf.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_-01.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_-1.0..json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_-2..json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_-NaN.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_.-1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_.2e-3.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_0.1.2.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_0.3e+.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_0.3e.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_0.e1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_0_capital_E+.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_0_capital_E.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_0e+.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_0e.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_1.0e+.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_1.0e-.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_1.0e.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_1_000.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_1eE2.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_2.e+3.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_2.e-3.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_2.e3.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_9.e+.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_Inf.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_NaN.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_U+FF11_fullwidth_digit_one.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_expression.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_hex_1_digit.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_hex_2_digits.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_infinity.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_invalid+-.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_invalid-negative-real.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_invalid-utf-8-in-bigger-int.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_invalid-utf-8-in-exponent.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_invalid-utf-8-in-int.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_minus_infinity.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_minus_sign_with_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_minus_space_1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_neg_int_starting_with_zero.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_neg_real_without_int_part.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_neg_with_garbage_at_end.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_real_garbage_after_e.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_real_with_invalid_utf8_after_e.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_real_without_fractional_part.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_starting_with_dot.json",
                //TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_then_00.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_with_alpha.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_with_alpha_char.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_number_with_leading_zero.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_bad_value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_bracket_key.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_comma_instead_of_colon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_double_colon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_emoji.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_garbage_at_end.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_key_with_single_quotes.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_missing_colon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_missing_key.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_missing_semicolon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_missing_value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_no-colon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_non_string_key.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_non_string_key_but_huge_number_instead.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_pi_in_key_and_trailing_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_repeated_null_null.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_several_trailing_commas.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_single_quote.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_trailing_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_trailing_comment.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_trailing_comment_open.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_trailing_comment_slash_open.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_trailing_comment_slash_open_incomplete.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_two_commas_in_a_row.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_unquoted_key.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_unterminated-value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_with_single_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_object_with_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_single_space.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_1_surrogate_then_escape u.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_1_surrogate_then_escape u1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_1_surrogate_then_escape u1x.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_1_surrogate_then_escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_UTF-16_incomplete_surrogate.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_UTF8_surrogate_U+D800.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_accentuated_char_no_quotes.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_backslash_00.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_escape_x.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_escaped_backslash_bad.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_escaped_ctrl_char_tab.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_escaped_emoji.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_incomplete_escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_incomplete_escaped_character.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_incomplete_surrogate_escape_invalid.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_invalid-utf-8-in-escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_invalid_backslash_esc.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_invalid_unicode_escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_invalid_utf-8.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_invalid_utf8_after_escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_iso_latin_1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_leading_uescaped_thinspace.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_lone_utf8_continuation_byte.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_no_quotes_with_bad_escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_overlong_sequence_2_bytes.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_overlong_sequence_6_bytes.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_overlong_sequence_6_bytes_null.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_single_doublequote.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_single_quote.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_single_string_no_double_quotes.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_start_escape_unclosed.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_unescaped_crtl_char.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_unescaped_newline.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_unescaped_tab.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_unicode_CapitalU.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_string_with_trailing_garbage.json",
                //!TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_100000_opening_arrays.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_3C.3E.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_3Cnull3E.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_U+2060_word_joined.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_UTF8_BOM_no_data.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_array_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_array_with_extra_array_close.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_array_with_unclosed_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_ascii-unicode-identifier.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_capitalized_True.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_close_unopened_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_comma_instead_of_closing_brace.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_double_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_end_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_incomplete_UTF8_BOM.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_lone-invalid-utf-8.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_lone-open-bracket.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_no_data.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_null-byte-outside-string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_number_with_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_object_followed_by_closing_object.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_object_unclosed_no_value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_object_with_comment.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_object_with_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_array_apostrophe.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_array_comma.json",
                //!TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_array_object.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_array_open_object.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_array_open_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_array_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_object.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_object_close_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_object_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_object_open_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_object_open_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_object_string_with_apostrophes.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_open_open.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_single_point.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_single_star.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_trailing_#.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_uescaped_LF_before_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_unclosed_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_unclosed_array_partial_null.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_unclosed_array_unfinished_false.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_unclosed_array_unfinished_true.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_unclosed_object.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_unicode-identifier.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_whitespace_U+2060_word_joiner.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite/test_parsing/n_structure_whitespace_formfeed.json"
            }
        )
    {
        CAPTURE(filename)
        std::ifstream f(filename);
        json _;
        CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
    }
}
  • cpp-test: [nst's JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

SECTION("n")
{
    for (const auto* filename :
            {
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_1_true_without_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_a_invalid_utf8.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_colon_instead_of_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_comma_after_close.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_comma_and_number.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_double_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_double_extra_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_extra_close.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_extra_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_incomplete.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_incomplete_invalid_value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_inner_array_no_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_invalid_utf8.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_items_separated_by_semicolon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_just_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_just_minus.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_missing_value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_newlines_unclosed.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_number_and_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_number_and_several_commas.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_spaces_vertical_tab_formfeed.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_star_inside.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_unclosed.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_unclosed_trailing_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_unclosed_with_new_lines.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_array_unclosed_with_object_inside.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_incomplete_false.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_incomplete_null.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_incomplete_true.json",
                //TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_multidigit_number_then_00.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_++.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_+1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_+Inf.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_-01.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_-1.0..json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_-2..json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_-NaN.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_.-1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_.2e-3.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0.1.2.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0.3e+.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0.3e.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0.e1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0_capital_E+.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0_capital_E.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0e+.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0e.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_1.0e+.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_1.0e-.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_1.0e.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_1_000.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_1eE2.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_2.e+3.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_2.e-3.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_2.e3.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_9.e+.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_Inf.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_NaN.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_U+FF11_fullwidth_digit_one.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_expression.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_hex_1_digit.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_infinity.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_invalid+-.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_invalid-negative-real.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-bigger-int.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-exponent.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-int.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_minus_infinity.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_minus_sign_with_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_minus_space_1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_neg_int_starting_with_zero.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_neg_real_without_int_part.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_neg_with_garbage_at_end.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_real_garbage_after_e.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_real_with_invalid_utf8_after_e.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_real_without_fractional_part.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_starting_with_dot.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_with_alpha.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_with_alpha_char.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_with_leading_zero.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_bad_value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_bracket_key.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_comma_instead_of_colon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_double_colon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_emoji.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_garbage_at_end.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_key_with_single_quotes.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_lone_continuation_byte_in_key_and_trailing_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_missing_colon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_missing_key.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_missing_semicolon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_missing_value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_no-colon.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_non_string_key.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_non_string_key_but_huge_number_instead.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_repeated_null_null.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_several_trailing_commas.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_single_quote.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_trailing_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_trailing_comment.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_trailing_comment_open.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_trailing_comment_slash_open.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_trailing_comment_slash_open_incomplete.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_two_commas_in_a_row.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_unquoted_key.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_unterminated-value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_with_single_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_with_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_single_space.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u1.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u1x.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_accentuated_char_no_quotes.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_backslash_00.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_escape_x.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_escaped_backslash_bad.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_escaped_ctrl_char_tab.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_escaped_emoji.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_incomplete_escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_incomplete_escaped_character.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_incomplete_surrogate.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_incomplete_surrogate_escape_invalid.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_invalid-utf-8-in-escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_invalid_backslash_esc.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_invalid_unicode_escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_invalid_utf8_after_escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_leading_uescaped_thinspace.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_no_quotes_with_bad_escape.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_single_doublequote.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_single_quote.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_single_string_no_double_quotes.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_start_escape_unclosed.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_unescaped_crtl_char.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_unescaped_newline.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_unescaped_tab.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_unicode_CapitalU.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_with_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_U+2060_word_joined.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_UTF8_BOM_no_data.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_angle_bracket_..json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_angle_bracket_null.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_array_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_array_with_extra_array_close.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_array_with_unclosed_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_ascii-unicode-identifier.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_capitalized_True.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_close_unopened_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_comma_instead_of_closing_brace.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_double_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_end_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_incomplete_UTF8_BOM.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_lone-invalid-utf-8.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_lone-open-bracket.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_no_data.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_null-byte-outside-string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_number_with_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_object_followed_by_closing_object.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_object_unclosed_no_value.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_object_with_comment.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_object_with_trailing_garbage.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_array_apostrophe.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_array_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_array_open_object.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_array_open_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_array_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_object.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_object_close_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_object_comma.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_object_open_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_object_open_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_object_string_with_apostrophes.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_open_open.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_single_eacute.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_single_star.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_trailing_#.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_uescaped_LF_before_string.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_array.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_array_partial_null.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_array_unfinished_false.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_array_unfinished_true.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unclosed_object.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_unicode-identifier.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_whitespace_U+2060_word_joiner.json",
                TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_whitespace_formfeed.json"
            }
        )
    {
        CAPTURE(filename)
        std::ifstream f(filename);
        json _;
        CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
        std::ifstream f2(filename);
        CHECK(!json::accept(f2));
    }
}
  • cpp-test: [compliance tests from json.org;expected failures] (tests/src/unit-testsuites.cpp)

SECTION("expected failures")
{
    for (const auto* filename :
            {
                //TEST_DATA_DIRECTORY "/json_tests/fail1.json",
                TEST_DATA_DIRECTORY "/json_tests/fail2.json",
                TEST_DATA_DIRECTORY "/json_tests/fail3.json",
                TEST_DATA_DIRECTORY "/json_tests/fail4.json",
                TEST_DATA_DIRECTORY "/json_tests/fail5.json",
                TEST_DATA_DIRECTORY "/json_tests/fail6.json",
                TEST_DATA_DIRECTORY "/json_tests/fail7.json",
                TEST_DATA_DIRECTORY "/json_tests/fail8.json",
                TEST_DATA_DIRECTORY "/json_tests/fail9.json",
                TEST_DATA_DIRECTORY "/json_tests/fail10.json",
                TEST_DATA_DIRECTORY "/json_tests/fail11.json",
                TEST_DATA_DIRECTORY "/json_tests/fail12.json",
                TEST_DATA_DIRECTORY "/json_tests/fail13.json",
                TEST_DATA_DIRECTORY "/json_tests/fail14.json",
                TEST_DATA_DIRECTORY "/json_tests/fail15.json",
                TEST_DATA_DIRECTORY "/json_tests/fail16.json",
                TEST_DATA_DIRECTORY "/json_tests/fail17.json",
                //TEST_DATA_DIRECTORY "/json_tests/fail18.json",
                TEST_DATA_DIRECTORY "/json_tests/fail19.json",
                TEST_DATA_DIRECTORY "/json_tests/fail20.json",
                TEST_DATA_DIRECTORY "/json_tests/fail21.json",
                TEST_DATA_DIRECTORY "/json_tests/fail22.json",
                TEST_DATA_DIRECTORY "/json_tests/fail23.json",
                TEST_DATA_DIRECTORY "/json_tests/fail24.json",
                TEST_DATA_DIRECTORY "/json_tests/fail25.json",
                TEST_DATA_DIRECTORY "/json_tests/fail26.json",
                TEST_DATA_DIRECTORY "/json_tests/fail27.json",
                TEST_DATA_DIRECTORY "/json_tests/fail28.json",
                TEST_DATA_DIRECTORY "/json_tests/fail29.json",
                TEST_DATA_DIRECTORY "/json_tests/fail30.json",
                TEST_DATA_DIRECTORY "/json_tests/fail31.json",
                TEST_DATA_DIRECTORY "/json_tests/fail32.json",
                TEST_DATA_DIRECTORY "/json_tests/fail33.json"
            })
    {
        CAPTURE(filename)
        std::ifstream f(filename);
        json _;
        CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.4.1#

If the service recognises the name candidate as string, then it accepts the name candidate.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;object;nonempty object] (TSF/tests/unit-class_parser_core.cpp)

SECTION("nonempty object")
{
    CHECK(accept_helper("{\"\": true, \"one\": 1, \"two\": null}"));
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_object_basic.json, /nst_json_testsuite2/test_parsing/y_object_duplicated_key.json, /nst_json_testsuite2/test_parsing/y_object_duplicated_key_and_value.json, /nst_json_testsuite2/test_parsing/y_object_empty.json, /nst_json_testsuite2/test_parsing/y_object_empty_key.json, /nst_json_testsuite2/test_parsing/y_object_escaped_null_in_key.json, /nst_json_testsuite2/test_parsing/y_object_extreme_numbers.json, /nst_json_testsuite2/test_parsing/y_object_long_strings.json, /nst_json_testsuite2/test_parsing/y_object_simple.json, /nst_json_testsuite2/test_parsing/y_object_string_unicode.json, /nst_json_testsuite2/test_parsing/y_object_with_newlines.json]

    • Description: Checks that various keys, particularly containing unicode characters, are accepted.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_basic.json

    {"asd":"sdf"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_duplicated_key.json

    {"a":"b","a":"c"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_duplicated_key_and_value.json

    {"a":"b","a":"b"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_empty.json

    {}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_empty_key.json

    {"":0}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_escaped_null_in_key.json

    {"foo\u0000bar": 42}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_extreme_numbers.json

    { "min": -1.0e+28, "max": 1.0e+28 }
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_long_strings.json

    {"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_simple.json

    {"a":[]}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_string_unicode.json

    {"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" }
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_with_newlines.json

    {
    "a": "b"
    }
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_basic.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_duplicated_key.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_duplicated_key_and_value.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_empty.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_empty_key.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_escaped_null_in_key.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_extreme_numbers.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_long_strings.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_simple.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_string_unicode.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_with_newlines.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [accept;names;strings;control characters] (TSF/tests/unit-objects.cpp)

SECTION("control characters")
{
    CHECK(json::accept("{\"foo\\u0000bar\":123}"));
    CHECK(json::accept("{\"foo\\u0001bar\":123}"));
    CHECK(json::accept("{\"foo\\u0002bar\":123}"));
    CHECK(json::accept("{\"foo\\u0003bar\":123}"));
    CHECK(json::accept("{\"foo\\u0004bar\":123}"));
    CHECK(json::accept("{\"foo\\u0005bar\":123}"));
    CHECK(json::accept("{\"foo\\u0006bar\":123}"));
    CHECK(json::accept("{\"foo\\u0007bar\":123}"));
    CHECK(json::accept("{\"foo\\u0008bar\":123}"));
    CHECK(json::accept("{\"foo\\u0009bar\":123}"));
    CHECK(json::accept("{\"foo\\u000abar\":123}"));
    CHECK(json::accept("{\"foo\\u000bbar\":123}"));
    CHECK(json::accept("{\"foo\\u000cbar\":123}"));
    CHECK(json::accept("{\"foo\\u000dbar\":123}"));
    CHECK(json::accept("{\"foo\\u000ebar\":123}"));
    CHECK(json::accept("{\"foo\\u000fbar\":123}"));
    CHECK(json::accept("{\"foo\\u0010bar\":123}"));
    CHECK(json::accept("{\"foo\\u0011bar\":123}"));
    CHECK(json::accept("{\"foo\\u0012bar\":123}"));
    CHECK(json::accept("{\"foo\\u0013bar\":123}"));
    CHECK(json::accept("{\"foo\\u0014bar\":123}"));
    CHECK(json::accept("{\"foo\\u0015bar\":123}"));
    CHECK(json::accept("{\"foo\\u0016bar\":123}"));
    CHECK(json::accept("{\"foo\\u0017bar\":123}"));
    CHECK(json::accept("{\"foo\\u0018bar\":123}"));
    CHECK(json::accept("{\"foo\\u0019bar\":123}"));
    CHECK(json::accept("{\"foo\\u001abar\":123}"));
    CHECK(json::accept("{\"foo\\u001bbar\":123}"));
    CHECK(json::accept("{\"foo\\u001cbar\":123}"));
    CHECK(json::accept("{\"foo\\u001dbar\":123}"));
    CHECK(json::accept("{\"foo\\u001ebar\":123}"));
    CHECK(json::accept("{\"foo\\u001fbar\":123}"));
}
  • cpp-test: [accept;names;strings;unicode] (TSF/tests/unit-objects.cpp)

SECTION("unicode")
{  
    // escaped
    CHECK(json::accept("{\"\\u0066\\u006f\\u006f\\u0062\\u0061\\u0072\":123}"));
    // unescaped
    CHECK(json::accept("{\"\u0066\u006f\u006f\u0062\u0061\u0072\":123}"));
}
  • cpp-test: [accept;names;strings;escaped UTF-16 surrogates] (TSF/tests/unit-objects.cpp)

SECTION("escaped UTF-16 surrogates")
{
    CHECK(json::accept("{\"\\ud834\\udd1e\":123}"));
    CHECK(json::accept("{\"\\ud83d\\ude00\":123}"));
    CHECK(json::accept("{\"\\ud83d\\udca9\":123}"));
    CHECK(json::accept("{\"\\ud83e\\udda5\":123}"));
    CHECK(json::accept("{\"\\ud83d\\ude80\":123}"));
    CHECK(json::accept("{\"\\ud840\\udc00\":123}"));
    CHECK(json::accept("{\"\\udbff\\udfff\":123}"));
    CHECK(json::accept("{\"\\ud83c\\udfc3\":123}"));
    CHECK(json::accept("{\"\\ud801\\udc37\":123}"));
    CHECK(json::accept("{\"\\ud83d\\udcbb\":123}"));
}
  • cpp-test: [accept;member separator] (TSF/tests/unit-objects.cpp)

SECTION("member separator")
{
    CHECK(json::accept("{\"foo\"\u003a\"bar\"}"));      //:
    CHECK(!json::accept("{\"foo\"\uff1a\"bar\"}"));     
    CHECK(!json::accept("{\"foo\"\ua789\"bar\"}"));
    CHECK(!json::accept("{\"foo\"\u005b\"bar\"}"));     //[
    CHECK(!json::accept("{\"foo\"\u007b\"bar\"}"));     //{
    CHECK(!json::accept("{\"foo\"\u005d\"bar\"}"));     //]
    CHECK(!json::accept("{\"foo\"\u007d\"bar\"}"));     //}
    CHECK(!json::accept("{\"foo\"\u002c\"bar\"}"));     //,
    CHECK(!json::accept("{\"foo\"\u003b\"bar\"}"));     //;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.4.2#

The service does not accept any other token as name.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_object_non_string_key.json, /nst_json_testsuite2/test_parsing/n_object_non_string_key_but_huge_number_instead.json]

    • Description: Checks that numbers as keys are rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_non_string_key.json

    {1:1}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_non_string_key_but_huge_number_instead.json

    {9999E9999:1}
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_non_string_key.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_non_string_key_but_huge_number_instead.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [accept;names;numbers] (TSF/tests/unit-objects.cpp)

SECTION("numbers")
{
    // cf. n_object_non_string_key.json, n_object_non_string_key_but_huge_number_instead.json, for some integers
    CHECK(!json::accept("{0.1:\"foo\"}"));
    CHECK(!json::accept("{3\u004542:\"foo\"}"));
    CHECK(!json::accept("{3.1415\u006542:\"foo\"}"));
    CHECK(!json::accept("{-15:\"foo\"}"));
}
  • cpp-test: [accept;names;arrays] (TSF/tests/unit-objects.cpp)

SECTION("arrays")
{
    CHECK(!json::accept("{[]:\"foo\"}"));
    CHECK(!json::accept("{[1]:\"foo\"}"));
    CHECK(!json::accept("{[1,\"foo\"]:\"bar\"}"));
}
  • cpp-test: [accept;names;objects] (TSF/tests/unit-objects.cpp)

SECTION("objects")
{
    CHECK(!json::accept("{{}:\"foo\"}"));
    CHECK(!json::accept("{{\"a\":1}:\"foo\"}"));
    CHECK(!json::accept("{{\"a\":1,\"b\":\"foo\"}:\"bar\"}"));
}
  • cpp-test: [accept;names;literals] (TSF/tests/unit-objects.cpp)

SECTION("literals")
{
    CHECK(!json::accept("true:\"foo\""));
    CHECK(!json::accept("false:\"foo\""));
    CHECK(!json::accept("null:\"foo\""));
}
  • cpp-test: [accept;member separator] (TSF/tests/unit-objects.cpp)

SECTION("member separator")
{
    CHECK(json::accept("{\"foo\"\u003a\"bar\"}"));      //:
    CHECK(!json::accept("{\"foo\"\uff1a\"bar\"}"));     
    CHECK(!json::accept("{\"foo\"\ua789\"bar\"}"));
    CHECK(!json::accept("{\"foo\"\u005b\"bar\"}"));     //[
    CHECK(!json::accept("{\"foo\"\u007b\"bar\"}"));     //{
    CHECK(!json::accept("{\"foo\"\u005d\"bar\"}"));     //]
    CHECK(!json::accept("{\"foo\"\u007d\"bar\"}"));     //}
    CHECK(!json::accept("{\"foo\"\u002c\"bar\"}"));     //,
    CHECK(!json::accept("{\"foo\"\u003b\"bar\"}"));     //;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.4.3#

If the service accepts the value-candidate as a singleton, then the value-candidate is accepted.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;object;nonempty object] (TSF/tests/unit-class_parser_core.cpp)

SECTION("nonempty object")
{
    CHECK(accept_helper("{\"\": true, \"one\": 1, \"two\": null}"));
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_object_basic.json, /nst_json_testsuite2/test_parsing/y_object_duplicated_key.json, /nst_json_testsuite2/test_parsing/y_object_duplicated_key_and_value.json, /nst_json_testsuite2/test_parsing/y_object_empty.json, /nst_json_testsuite2/test_parsing/y_object_empty_key.json, /nst_json_testsuite2/test_parsing/y_object_escaped_null_in_key.json, /nst_json_testsuite2/test_parsing/y_object_extreme_numbers.json, /nst_json_testsuite2/test_parsing/y_object_long_strings.json, /nst_json_testsuite2/test_parsing/y_object_simple.json, /nst_json_testsuite2/test_parsing/y_object_string_unicode.json, /nst_json_testsuite2/test_parsing/y_object_with_newlines.json]

    • Description: Checks that various strings and numbers are accepted values.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_basic.json

    {"asd":"sdf"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_duplicated_key.json

    {"a":"b","a":"c"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_duplicated_key_and_value.json

    {"a":"b","a":"b"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_empty.json

    {}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_empty_key.json

    {"":0}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_escaped_null_in_key.json

    {"foo\u0000bar": 42}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_extreme_numbers.json

    { "min": -1.0e+28, "max": 1.0e+28 }
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_long_strings.json

    {"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_simple.json

    {"a":[]}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_string_unicode.json

    {"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" }
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_object_with_newlines.json

    {
    "a": "b"
    }
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_basic.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_duplicated_key.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_duplicated_key_and_value.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_empty.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_empty_key.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_escaped_null_in_key.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_extreme_numbers.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_long_strings.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_simple.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_string_unicode.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_object_with_newlines.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [accept;member separator] (TSF/tests/unit-objects.cpp)

SECTION("member separator")
{
    CHECK(json::accept("{\"foo\"\u003a\"bar\"}"));      //:
    CHECK(!json::accept("{\"foo\"\uff1a\"bar\"}"));     
    CHECK(!json::accept("{\"foo\"\ua789\"bar\"}"));
    CHECK(!json::accept("{\"foo\"\u005b\"bar\"}"));     //[
    CHECK(!json::accept("{\"foo\"\u007b\"bar\"}"));     //{
    CHECK(!json::accept("{\"foo\"\u005d\"bar\"}"));     //]
    CHECK(!json::accept("{\"foo\"\u007d\"bar\"}"));     //}
    CHECK(!json::accept("{\"foo\"\u002c\"bar\"}"));     //,
    CHECK(!json::accept("{\"foo\"\u003b\"bar\"}"));     //;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.5#

The service does not accept objects with improper members.

Supported Requests:

Supporting Items:

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_object_trailing_comma.json, /nst_json_testsuite2/test_parsing/n_object_two_commas_in_a_row.json]

    • Description: Checks that the empty member in a nonempty object is rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_trailing_comma.json

    {"id":0,}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_two_commas_in_a_row.json

    {"a":"b",,"c":"d"}
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_trailing_comma.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_two_commas_in_a_row.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.5.1#

If the service does not accept any name candidate as singleton, then the service does not accept the object candidate.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_object_single_quote.json, /nst_json_testsuite2/test_parsing/n_object_unquoted_key.json, /nst_json_testsuite2/test_parsing/n_object_non_string_key.json, /nst_json_testsuite2/test_parsing/n_object_non_string_key_but_huge_number_instead.json, /nst_json_testsuite2/test_parsing/n_object_key_with_single_quotes.json, /nst_json_testsuite2/test_parsing/n_object_bracket_key.json, /nst_json_testsuite2/test_parsing/n_object_unquoted_key.json]

    • Description: Checks that invalid names are rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_single_quote.json

    {'a':0}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_unquoted_key.json

    {a: "b"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_non_string_key.json

    {1:1}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_non_string_key_but_huge_number_instead.json

    {9999E9999:1}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_key_with_single_quotes.json

    {key: 'value'}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_bracket_key.json

    {[: "x"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_unquoted_key.json

    {a: "b"}
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_bracket_key.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_key_with_single_quotes.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_non_string_key.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_non_string_key_but_huge_number_instead.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_single_quote.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_unquoted_key.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/i_object_key_lone_2nd_surrogate.json]

    • Description: Checks that string with invalid utf16 surrogate is rejected as name

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/i_object_key_lone_2nd_surrogate.json

    {"\uDFAA":0}
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;i -> n] (tests/src/unit-testsuites.cpp)

    SECTION("i -> n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/i_object_key_lone_2nd_surrogate.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::exception&); // could be parse_error or out_of_range
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [accept;member separator] (TSF/tests/unit-objects.cpp)

SECTION("member separator")
{
    CHECK(json::accept("{\"foo\"\u003a\"bar\"}"));      //:
    CHECK(!json::accept("{\"foo\"\uff1a\"bar\"}"));     
    CHECK(!json::accept("{\"foo\"\ua789\"bar\"}"));
    CHECK(!json::accept("{\"foo\"\u005b\"bar\"}"));     //[
    CHECK(!json::accept("{\"foo\"\u007b\"bar\"}"));     //{
    CHECK(!json::accept("{\"foo\"\u005d\"bar\"}"));     //]
    CHECK(!json::accept("{\"foo\"\u007d\"bar\"}"));     //}
    CHECK(!json::accept("{\"foo\"\u002c\"bar\"}"));     //,
    CHECK(!json::accept("{\"foo\"\u003b\"bar\"}"));     //;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.5.2#

If the service does not accept any value candidate as singleton, then the service does not accept the object candidate.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_object_bad_value.json]

    • Description: Checks that the invalid literal “truth” as value is rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_bad_value.json

    ["x", truth]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_bad_value.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [accept;member separator] (TSF/tests/unit-objects.cpp)

SECTION("member separator")
{
    CHECK(json::accept("{\"foo\"\u003a\"bar\"}"));      //:
    CHECK(!json::accept("{\"foo\"\uff1a\"bar\"}"));     
    CHECK(!json::accept("{\"foo\"\ua789\"bar\"}"));
    CHECK(!json::accept("{\"foo\"\u005b\"bar\"}"));     //[
    CHECK(!json::accept("{\"foo\"\u007b\"bar\"}"));     //{
    CHECK(!json::accept("{\"foo\"\u005d\"bar\"}"));     //]
    CHECK(!json::accept("{\"foo\"\u007d\"bar\"}"));     //}
    CHECK(!json::accept("{\"foo\"\u002c\"bar\"}"));     //,
    CHECK(!json::accept("{\"foo\"\u003b\"bar\"}"));     //;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.6#

The service accept the nested objects.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/json.org/1.json, /json.org/2.json, /json.org/3.json, /json.org/4.json, /json.org/5.json]

    • Description: Checks that various nested objects are accepted.

    • JSON Testsuite: /json.org/1.json

    {
       "glossary": {
           "title": "example glossary",
       	"GlossDiv": {
               "title": "S",
       		"GlossList": {
                   "GlossEntry": {
                       "ID": "SGML",
       				"SortAs": "SGML",
       				"GlossTerm": "Standard Generalized Markup Language",
       				"Acronym": "SGML",
       				"Abbrev": "ISO 8879:1986",
       				"GlossDef": {
                           "para": "A meta-markup language, used to create markup languages such as DocBook.",
       					"GlossSeeAlso": ["GML", "XML"]
                       },
       				"GlossSee": "markup"
                   }
               }
           }
       }
    }
    
    • JSON Testsuite: /json.org/2.json

    {"menu": {
     "id": "file",
     "value": "File",
     "popup": {
       "menuitem": [
         {"value": "New", "onclick": "CreateNewDoc()"},
         {"value": "Open", "onclick": "OpenDoc()"},
         {"value": "Close", "onclick": "CloseDoc()"}
       ]
     }
    }}
    
    • JSON Testsuite: /json.org/3.json

    Link to file [Content too large - 26 lines]

    • JSON Testsuite: /json.org/4.json

    Link to file [Content too large - 88 lines]

    • JSON Testsuite: /json.org/5.json

    Link to file [Content too large - 27 lines]

    • cpp-test: [json.org examples] (tests/src/unit-testsuites.cpp)

    TEST_CASE("json.org examples")
    {
        // here, we list all JSON values from https://json.org/example
        using FilePtr = std::unique_ptr<FILE, int(*)(FILE*)>;
    
        SECTION("1.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/1.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("2.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/2.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("3.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/3.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("4.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/4.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("5.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/5.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
        SECTION("FILE 1.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/1.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 2.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/2.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 3.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/3.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 4.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/4.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 5.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/5.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    }
    
  • cpp-test: [accept;member separator] (TSF/tests/unit-objects.cpp)

SECTION("member separator")
{
    CHECK(json::accept("{\"foo\"\u003a\"bar\"}"));      //:
    CHECK(!json::accept("{\"foo\"\uff1a\"bar\"}"));     
    CHECK(!json::accept("{\"foo\"\ua789\"bar\"}"));
    CHECK(!json::accept("{\"foo\"\u005b\"bar\"}"));     //[
    CHECK(!json::accept("{\"foo\"\u007b\"bar\"}"));     //{
    CHECK(!json::accept("{\"foo\"\u005d\"bar\"}"));     //]
    CHECK(!json::accept("{\"foo\"\u007d\"bar\"}"));     //}
    CHECK(!json::accept("{\"foo\"\u002c\"bar\"}"));     //,
    CHECK(!json::accept("{\"foo\"\u003b\"bar\"}"));     //;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.6.0#

The acceptance of nested objects does not depend on the depth of nesting.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/json.org/1.json, /json.org/2.json, /json.org/3.json, /json.org/4.json, /json.org/5.json]

    • Description: Checks that various nested objects are accepted.

    • JSON Testsuite: /json.org/1.json

    {
       "glossary": {
           "title": "example glossary",
       	"GlossDiv": {
               "title": "S",
       		"GlossList": {
                   "GlossEntry": {
                       "ID": "SGML",
       				"SortAs": "SGML",
       				"GlossTerm": "Standard Generalized Markup Language",
       				"Acronym": "SGML",
       				"Abbrev": "ISO 8879:1986",
       				"GlossDef": {
                           "para": "A meta-markup language, used to create markup languages such as DocBook.",
       					"GlossSeeAlso": ["GML", "XML"]
                       },
       				"GlossSee": "markup"
                   }
               }
           }
       }
    }
    
    • JSON Testsuite: /json.org/2.json

    {"menu": {
     "id": "file",
     "value": "File",
     "popup": {
       "menuitem": [
         {"value": "New", "onclick": "CreateNewDoc()"},
         {"value": "Open", "onclick": "OpenDoc()"},
         {"value": "Close", "onclick": "CloseDoc()"}
       ]
     }
    }}
    
    • JSON Testsuite: /json.org/3.json

    Link to file [Content too large - 26 lines]

    • JSON Testsuite: /json.org/4.json

    Link to file [Content too large - 88 lines]

    • JSON Testsuite: /json.org/5.json

    Link to file [Content too large - 27 lines]

    • cpp-test: [json.org examples] (tests/src/unit-testsuites.cpp)

    TEST_CASE("json.org examples")
    {
        // here, we list all JSON values from https://json.org/example
        using FilePtr = std::unique_ptr<FILE, int(*)(FILE*)>;
    
        SECTION("1.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/1.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("2.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/2.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("3.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/3.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("4.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/4.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("5.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/5.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
        SECTION("FILE 1.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/1.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 2.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/2.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 3.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/3.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 4.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/4.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 5.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/5.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    }
    
  • cpp-test: [accept;member separator] (TSF/tests/unit-objects.cpp)

SECTION("member separator")
{
    CHECK(json::accept("{\"foo\"\u003a\"bar\"}"));      //:
    CHECK(!json::accept("{\"foo\"\uff1a\"bar\"}"));     
    CHECK(!json::accept("{\"foo\"\ua789\"bar\"}"));
    CHECK(!json::accept("{\"foo\"\u005b\"bar\"}"));     //[
    CHECK(!json::accept("{\"foo\"\u007b\"bar\"}"));     //{
    CHECK(!json::accept("{\"foo\"\u005d\"bar\"}"));     //]
    CHECK(!json::accept("{\"foo\"\u007d\"bar\"}"));     //}
    CHECK(!json::accept("{\"foo\"\u002c\"bar\"}"));     //,
    CHECK(!json::accept("{\"foo\"\u003b\"bar\"}"));     //;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.7#

The service does only accept comma as member separator.

Supported Requests:

Supporting Items:

References:

None

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.7.1#

The service accepts comma as member separator.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/json.org/1.json, /json.org/2.json, /json.org/3.json, /json.org/4.json, /json.org/5.json, /json.org/1.json, /json.org/2.json, /json.org/3.json, /json.org/4.json, /json.org/5.json]

    • Description: Checks that various arrays with more than one value are accepted.

    • JSON Testsuite: /json.org/1.json

    {
       "glossary": {
           "title": "example glossary",
       	"GlossDiv": {
               "title": "S",
       		"GlossList": {
                   "GlossEntry": {
                       "ID": "SGML",
       				"SortAs": "SGML",
       				"GlossTerm": "Standard Generalized Markup Language",
       				"Acronym": "SGML",
       				"Abbrev": "ISO 8879:1986",
       				"GlossDef": {
                           "para": "A meta-markup language, used to create markup languages such as DocBook.",
       					"GlossSeeAlso": ["GML", "XML"]
                       },
       				"GlossSee": "markup"
                   }
               }
           }
       }
    }
    
    • JSON Testsuite: /json.org/2.json

    {"menu": {
     "id": "file",
     "value": "File",
     "popup": {
       "menuitem": [
         {"value": "New", "onclick": "CreateNewDoc()"},
         {"value": "Open", "onclick": "OpenDoc()"},
         {"value": "Close", "onclick": "CloseDoc()"}
       ]
     }
    }}
    
    • JSON Testsuite: /json.org/3.json

    Link to file [Content too large - 26 lines]

    • JSON Testsuite: /json.org/4.json

    Link to file [Content too large - 88 lines]

    • JSON Testsuite: /json.org/5.json

    Link to file [Content too large - 27 lines]

    • JSON Testsuite: /json.org/1.json

    {
       "glossary": {
           "title": "example glossary",
       	"GlossDiv": {
               "title": "S",
       		"GlossList": {
                   "GlossEntry": {
                       "ID": "SGML",
       				"SortAs": "SGML",
       				"GlossTerm": "Standard Generalized Markup Language",
       				"Acronym": "SGML",
       				"Abbrev": "ISO 8879:1986",
       				"GlossDef": {
                           "para": "A meta-markup language, used to create markup languages such as DocBook.",
       					"GlossSeeAlso": ["GML", "XML"]
                       },
       				"GlossSee": "markup"
                   }
               }
           }
       }
    }
    
    • JSON Testsuite: /json.org/2.json

    {"menu": {
     "id": "file",
     "value": "File",
     "popup": {
       "menuitem": [
         {"value": "New", "onclick": "CreateNewDoc()"},
         {"value": "Open", "onclick": "OpenDoc()"},
         {"value": "Close", "onclick": "CloseDoc()"}
       ]
     }
    }}
    
    • JSON Testsuite: /json.org/3.json

    Link to file [Content too large - 26 lines]

    • JSON Testsuite: /json.org/4.json

    Link to file [Content too large - 88 lines]

    • JSON Testsuite: /json.org/5.json

    Link to file [Content too large - 27 lines]

    • cpp-test: [json.org examples] (tests/src/unit-testsuites.cpp)

    TEST_CASE("json.org examples")
    {
        // here, we list all JSON values from https://json.org/example
        using FilePtr = std::unique_ptr<FILE, int(*)(FILE*)>;
    
        SECTION("1.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/1.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("2.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/2.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("3.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/3.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("4.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/4.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
    
        SECTION("5.json")
        {
            std::ifstream f(TEST_DATA_DIRECTORY "/json.org/5.json");
            json j;
            CHECK_NOTHROW(f >> j);
        }
        SECTION("FILE 1.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/1.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 2.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/2.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 3.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/3.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 4.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/4.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    
        SECTION("FILE 5.json")
        {
            const FilePtr f(std::fopen(TEST_DATA_DIRECTORY "/json.org/5.json", "r"), &std::fclose);
            json _;
            CHECK_NOTHROW(_ = json::parse(f.get()));
        }
    }
    
  • cpp-test: [accept;member separator] (TSF/tests/unit-objects.cpp)

SECTION("member separator")
{
    CHECK(json::accept("{\"foo\"\u003a\"bar\"}"));      //:
    CHECK(!json::accept("{\"foo\"\uff1a\"bar\"}"));     
    CHECK(!json::accept("{\"foo\"\ua789\"bar\"}"));
    CHECK(!json::accept("{\"foo\"\u005b\"bar\"}"));     //[
    CHECK(!json::accept("{\"foo\"\u007b\"bar\"}"));     //{
    CHECK(!json::accept("{\"foo\"\u005d\"bar\"}"));     //]
    CHECK(!json::accept("{\"foo\"\u007d\"bar\"}"));     //}
    CHECK(!json::accept("{\"foo\"\u002c\"bar\"}"));     //,
    CHECK(!json::accept("{\"foo\"\u003b\"bar\"}"));     //;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-06.7.2#

The service does not accept any other member separator.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_object_comma_instead_of_colon.json]

    • Description: Checks that comma instead of colon is rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_comma_instead_of_colon.json

    {"x", null}
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_comma_instead_of_colon.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_object_double_colon.json]

    • Description: Checks that double colon is rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_double_colon.json

    {"x"::"b"}
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_double_colon.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_object_missing_colon.json, /nst_json_testsuite2/test_parsing/n_object_missing_semicolon.json, /nst_json_testsuite2/test_parsing/n_object_missing_semicolon.json]

    • Description: Checks that the empty member separator is rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_missing_colon.json

    {"a" b}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_missing_semicolon.json

    {"a" "b"}
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_object_missing_semicolon.json

    {"a" "b"}
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_missing_colon.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_object_missing_semicolon.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [accept;member separator] (TSF/tests/unit-objects.cpp)

SECTION("member separator")
{
    CHECK(json::accept("{\"foo\"\u003a\"bar\"}"));      //:
    CHECK(!json::accept("{\"foo\"\uff1a\"bar\"}"));     
    CHECK(!json::accept("{\"foo\"\ua789\"bar\"}"));
    CHECK(!json::accept("{\"foo\"\u005b\"bar\"}"));     //[
    CHECK(!json::accept("{\"foo\"\u007b\"bar\"}"));     //{
    CHECK(!json::accept("{\"foo\"\u005d\"bar\"}"));     //]
    CHECK(!json::accept("{\"foo\"\u007d\"bar\"}"));     //}
    CHECK(!json::accept("{\"foo\"\u002c\"bar\"}"));     //,
    CHECK(!json::accept("{\"foo\"\u003b\"bar\"}"));     //;
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-07#

The service accepts and rejects strings according to RFC8259 §7.

Supported Requests:

Supporting Items:

References:

  • function: [lexer::scan_string] (include/nlohmann/detail/input/lexer.hpp)

    • Description: function which scans a string and verifies en passant that the string is in accordance with RFC8259

token_type scan_string()
{
    // reset token_buffer (ignore opening quote)
    reset();

    // we entered the function by reading an open quote
    JSON_ASSERT(current == '\"');

    while (true)
    {
        // get next character
        switch (get())
        {
            // end of file while parsing string
            case char_traits<char_type>::eof():
            {
                error_message = "invalid string: missing closing quote";
                return token_type::parse_error;
            }

            // closing quote
            case '\"':
            {
                return token_type::value_string;
            }

            // escapes
            case '\\':
            {
                switch (get())
                {
                    // quotation mark
                    case '\"':
                        add('\"');
                        break;
                    // reverse solidus
                    case '\\':
                        add('\\');
                        break;
                    // solidus
                    case '/':
                        add('/');
                        break;
                    // backspace
                    case 'b':
                        add('\b');
                        break;
                    // form feed
                    case 'f':
                        add('\f');
                        break;
                    // line feed
                    case 'n':
                        add('\n');
                        break;
                    // carriage return
                    case 'r':
                        add('\r');
                        break;
                    // tab
                    case 't':
                        add('\t');
                        break;

                    // unicode escapes
                    case 'u':
                    {
                        const int codepoint1 = get_codepoint();
                        int codepoint = codepoint1; // start with codepoint1

                        if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
                        {
                            error_message = "invalid string: '\\u' must be followed by 4 hex digits";
                            return token_type::parse_error;
                        }

                        // check if code point is a high surrogate
                        if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
                        {
                            // expect next \uxxxx entry
                            if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
                            {
                                const int codepoint2 = get_codepoint();

                                if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
                                {
                                    error_message = "invalid string: '\\u' must be followed by 4 hex digits";
                                    return token_type::parse_error;
                                }

                                // check if codepoint2 is a low surrogate
                                if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
                                {
                                    // overwrite codepoint
                                    codepoint = static_cast<int>(
                                                    // high surrogate occupies the most significant 22 bits
                                                    (static_cast<unsigned int>(codepoint1) << 10u)
                                                    // low surrogate occupies the least significant 15 bits
                                                    + static_cast<unsigned int>(codepoint2)
                                                    // there is still the 0xD800, 0xDC00 and 0x10000 noise
                                                    // in the result, so we have to subtract with:
                                                    // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
                                                    - 0x35FDC00u);
                                }
                                else
                                {
                                    error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
                                    return token_type::parse_error;
                                }
                            }
                            else
                            {
                                error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
                                return token_type::parse_error;
                            }
                        }
                        else
                        {
                            if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
                            {
                                error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
                                return token_type::parse_error;
                            }
                        }

                        // result of the above calculation yields a proper codepoint
                        JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);

                        // translate codepoint into bytes
                        if (codepoint < 0x80)
                        {
                            // 1-byte characters: 0xxxxxxx (ASCII)
                            add(static_cast<char_int_type>(codepoint));
                        }
                        else if (codepoint <= 0x7FF)
                        {
                            // 2-byte characters: 110xxxxx 10xxxxxx
                            add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
                            add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
                        }
                        else if (codepoint <= 0xFFFF)
                        {
                            // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
                            add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
                            add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
                            add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
                        }
                        else
                        {
                            // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
                            add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
                            add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
                            add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
                            add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
                        }

                        break;
                    }

                    // other characters after escape
                    default:
                        error_message = "invalid string: forbidden character after backslash";
                        return token_type::parse_error;
                }

                break;
            }

            // invalid control characters
            case 0x00:
            {
                error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
                return token_type::parse_error;
            }

            case 0x01:
            {
                error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
                return token_type::parse_error;
            }

            case 0x02:
            {
                error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
                return token_type::parse_error;
            }

            case 0x03:
            {
                error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
                return token_type::parse_error;
            }

            case 0x04:
            {
                error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
                return token_type::parse_error;
            }

            case 0x05:
            {
                error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
                return token_type::parse_error;
            }

            case 0x06:
            {
                error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
                return token_type::parse_error;
            }

            case 0x07:
            {
                error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
                return token_type::parse_error;
            }

            case 0x08:
            {
                error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
                return token_type::parse_error;
            }

            case 0x09:
            {
                error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
                return token_type::parse_error;
            }

            case 0x0A:
            {
                error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
                return token_type::parse_error;
            }

            case 0x0B:
            {
                error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
                return token_type::parse_error;
            }

            case 0x0C:
            {
                error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
                return token_type::parse_error;
            }

            case 0x0D:
            {
                error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
                return token_type::parse_error;
            }

            case 0x0E:
            {
                error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
                return token_type::parse_error;
            }

            case 0x0F:
            {
                error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
                return token_type::parse_error;
            }

            case 0x10:
            {
                error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
                return token_type::parse_error;
            }

            case 0x11:
            {
                error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
                return token_type::parse_error;
            }

            case 0x12:
            {
                error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
                return token_type::parse_error;
            }

            case 0x13:
            {
                error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
                return token_type::parse_error;
            }

            case 0x14:
            {
                error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
                return token_type::parse_error;
            }

            case 0x15:
            {
                error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
                return token_type::parse_error;
            }

            case 0x16:
            {
                error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
                return token_type::parse_error;
            }

            case 0x17:
            {
                error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
                return token_type::parse_error;
            }

            case 0x18:
            {
                error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
                return token_type::parse_error;
            }

            case 0x19:
            {
                error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
                return token_type::parse_error;
            }

            case 0x1A:
            {
                error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
                return token_type::parse_error;
            }

            case 0x1B:
            {
                error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
                return token_type::parse_error;
            }

            case 0x1C:
            {
                error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
                return token_type::parse_error;
            }

            case 0x1D:
            {
                error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
                return token_type::parse_error;
            }

            case 0x1E:
            {
                error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
                return token_type::parse_error;
            }

            case 0x1F:
            {
                error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
                return token_type::parse_error;
            }

            // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
            case 0x20:
            case 0x21:
            case 0x23:
            case 0x24:
            case 0x25:
            case 0x26:
            case 0x27:
            case 0x28:
            case 0x29:
            case 0x2A:
            case 0x2B:
            case 0x2C:
            case 0x2D:
            case 0x2E:
            case 0x2F:
            case 0x30:
            case 0x31:
            case 0x32:
            case 0x33:
            case 0x34:
            case 0x35:
            case 0x36:
            case 0x37:
            case 0x38:
            case 0x39:
            case 0x3A:
            case 0x3B:
            case 0x3C:
            case 0x3D:
            case 0x3E:
            case 0x3F:
            case 0x40:
            case 0x41:
            case 0x42:
            case 0x43:
            case 0x44:
            case 0x45:
            case 0x46:
            case 0x47:
            case 0x48:
            case 0x49:
            case 0x4A:
            case 0x4B:
            case 0x4C:
            case 0x4D:
            case 0x4E:
            case 0x4F:
            case 0x50:
            case 0x51:
            case 0x52:
            case 0x53:
            case 0x54:
            case 0x55:
            case 0x56:
            case 0x57:
            case 0x58:
            case 0x59:
            case 0x5A:
            case 0x5B:
            case 0x5D:
            case 0x5E:
            case 0x5F:
            case 0x60:
            case 0x61:
            case 0x62:
            case 0x63:
            case 0x64:
            case 0x65:
            case 0x66:
            case 0x67:
            case 0x68:
            case 0x69:
            case 0x6A:
            case 0x6B:
            case 0x6C:
            case 0x6D:
            case 0x6E:
            case 0x6F:
            case 0x70:
            case 0x71:
            case 0x72:
            case 0x73:
            case 0x74:
            case 0x75:
            case 0x76:
            case 0x77:
            case 0x78:
            case 0x79:
            case 0x7A:
            case 0x7B:
            case 0x7C:
            case 0x7D:
            case 0x7E:
            case 0x7F:
            {
                add(current);
                break;
            }

            // U+0080..U+07FF: bytes C2..DF 80..BF
            case 0xC2:
            case 0xC3:
            case 0xC4:
            case 0xC5:
            case 0xC6:
            case 0xC7:
            case 0xC8:
            case 0xC9:
            case 0xCA:
            case 0xCB:
            case 0xCC:
            case 0xCD:
            case 0xCE:
            case 0xCF:
            case 0xD0:
            case 0xD1:
            case 0xD2:
            case 0xD3:
            case 0xD4:
            case 0xD5:
            case 0xD6:
            case 0xD7:
            case 0xD8:
            case 0xD9:
            case 0xDA:
            case 0xDB:
            case 0xDC:
            case 0xDD:
            case 0xDE:
            case 0xDF:
            {
                if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
                {
                    return token_type::parse_error;
                }
                break;
            }

            // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
            case 0xE0:
            {
                if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
                {
                    return token_type::parse_error;
                }
                break;
            }

            // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
            // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
            case 0xE1:
            case 0xE2:
            case 0xE3:
            case 0xE4:
            case 0xE5:
            case 0xE6:
            case 0xE7:
            case 0xE8:
            case 0xE9:
            case 0xEA:
            case 0xEB:
            case 0xEC:
            case 0xEE:
            case 0xEF:
            {
                if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
                {
                    return token_type::parse_error;
                }
                break;
            }

            // U+D000..U+D7FF: bytes ED 80..9F 80..BF
            case 0xED:
            {
                if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
                {
                    return token_type::parse_error;
                }
                break;
            }

            // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
            case 0xF0:
            {
                if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
                {
                    return token_type::parse_error;
                }
                break;
            }

            // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
            case 0xF1:
            case 0xF2:
            case 0xF3:
            {
                if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
                {
                    return token_type::parse_error;
                }
                break;
            }

            // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
            case 0xF4:
            {
                if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
                {
                    return token_type::parse_error;
                }
                break;
            }

            // remaining bytes (80..C1 and F5..FF) are ill-formed
            default:
            {
                error_message = "invalid string: ill-formed UTF-8 byte";
                return token_type::parse_error;
            }
        }
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-07.1#

The service does accept empty string.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;string] (TSF/tests/unit-class_parser_core.cpp)

SECTION("string")
{
    // empty string
    CHECK(accept_helper("\"\""));

    SECTION("errors")
    {
        // error: tab in string
        CHECK(accept_helper("\"\t\"") == false);
        // error: newline in string
        CHECK(accept_helper("\"\n\"") == false);
        CHECK(accept_helper("\"\r\"") == false);
        // error: backspace in string
        CHECK(accept_helper("\"\b\"") == false);
        // improve code coverage
        CHECK(accept_helper("\uFF01") == false);
        CHECK(accept_helper("[-4:1,]") == false);
        // unescaped control characters
        CHECK(accept_helper("\"\x00\"") == false); // NOLINT(bugprone-string-literal-with-embedded-nul)
        CHECK(accept_helper("\"\x01\"") == false);
        CHECK(accept_helper("\"\x02\"") == false);
        CHECK(accept_helper("\"\x03\"") == false);
        CHECK(accept_helper("\"\x04\"") == false);
        CHECK(accept_helper("\"\x05\"") == false);
        CHECK(accept_helper("\"\x06\"") == false);
        CHECK(accept_helper("\"\x07\"") == false);
        CHECK(accept_helper("\"\x08\"") == false);
        CHECK(accept_helper("\"\x09\"") == false);
        CHECK(accept_helper("\"\x0a\"") == false);
        CHECK(accept_helper("\"\x0b\"") == false);
        CHECK(accept_helper("\"\x0c\"") == false);
        CHECK(accept_helper("\"\x0d\"") == false);
        CHECK(accept_helper("\"\x0e\"") == false);
        CHECK(accept_helper("\"\x0f\"") == false);
        CHECK(accept_helper("\"\x10\"") == false);
        CHECK(accept_helper("\"\x11\"") == false);
        CHECK(accept_helper("\"\x12\"") == false);
        CHECK(accept_helper("\"\x13\"") == false);
        CHECK(accept_helper("\"\x14\"") == false);
        CHECK(accept_helper("\"\x15\"") == false);
        CHECK(accept_helper("\"\x16\"") == false);
        CHECK(accept_helper("\"\x17\"") == false);
        CHECK(accept_helper("\"\x18\"") == false);
        CHECK(accept_helper("\"\x19\"") == false);
        CHECK(accept_helper("\"\x1a\"") == false);
        CHECK(accept_helper("\"\x1b\"") == false);
        CHECK(accept_helper("\"\x1c\"") == false);
        CHECK(accept_helper("\"\x1d\"") == false);
        CHECK(accept_helper("\"\x1e\"") == false);
        CHECK(accept_helper("\"\x1f\"") == false);
    }

    SECTION("escaped")
    {
        // quotation mark "\""
        auto r1 = R"("\"")"_json;
        CHECK(accept_helper("\"\\\"\""));
        // reverse solidus "\\"
        auto r2 = R"("\\")"_json;
        CHECK(accept_helper("\"\\\\\""));
        // solidus
        CHECK(accept_helper("\"\\/\""));
        // backspace
        CHECK(accept_helper("\"\\b\""));
        // formfeed
        CHECK(accept_helper("\"\\f\""));
        // newline
        CHECK(accept_helper("\"\\n\""));
        // carriage return
        CHECK(accept_helper("\"\\r\""));
        // horizontal tab
        CHECK(accept_helper("\"\\t\""));

        CHECK(accept_helper("\"\\u0001\""));
        CHECK(accept_helper("\"\\u000a\""));
        CHECK(accept_helper("\"\\u00b0\""));
        CHECK(accept_helper("\"\\u0c00\""));
        CHECK(accept_helper("\"\\ud000\""));
        CHECK(accept_helper("\"\\u000E\""));
        CHECK(accept_helper("\"\\u00F0\""));
        CHECK(accept_helper("\"\\u0100\""));
        CHECK(accept_helper("\"\\u2000\""));
        CHECK(accept_helper("\"\\uFFFF\""));
        CHECK(accept_helper("\"\\u20AC\""));
        CHECK(accept_helper("\"\""));
        CHECK(accept_helper("\"🎈\""));

        CHECK(accept_helper("\"\\ud80c\\udc60\""));
        CHECK(accept_helper("\"\\ud83c\\udf1e\""));
    }
}
  • cpp-test: [compliance tests from nativejson-benchmark;strings] (tests/src/unit-testsuites.cpp)

SECTION("strings")
{
    auto TEST_STRING = [](const std::string & json_string, const std::string & expected)
    {
        CAPTURE(json_string)
        CAPTURE(expected)
        CHECK(json::parse(json_string)[0].get<std::string>() == expected);
    };

    TEST_STRING("[\"\"]", "");
    TEST_STRING("[\"Hello\"]", "Hello");
    TEST_STRING(R"(["Hello\nWorld"])", "Hello\nWorld");
    //TEST_STRING("[\"Hello\\u0000World\"]", "Hello\0World");
    TEST_STRING(R"(["\"\\/\b\f\n\r\t"])", "\"\\/\b\f\n\r\t");
    TEST_STRING(R"(["\u0024"])", "$");         // Dollar sign U+0024
    TEST_STRING(R"(["\u00A2"])", "\xC2\xA2");     // Cents sign U+00A2
    TEST_STRING(R"(["\u20AC"])", "\xE2\x82\xAC"); // Euro sign U+20AC
    TEST_STRING(R"(["\uD834\uDD1E"])", "\xF0\x9D\x84\x9E");  // G clef sign U+1D11E
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-07.2#

The service does not accept the improperly bounded strings.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;parse errors (accept)] (TSF/tests/unit-class_parser_core.cpp)

SECTION("parse errors (accept)")
{
    // unexpected end of number
    CHECK(accept_helper("0.") == false);
    CHECK(accept_helper("-") == false);
    CHECK(accept_helper("--") == false);
    CHECK(accept_helper("-0.") == false);
    CHECK(accept_helper("-.") == false);
    CHECK(accept_helper("-:") == false);
    CHECK(accept_helper("0.:") == false);
    CHECK(accept_helper("e.") == false);
    CHECK(accept_helper("1e.") == false);
    CHECK(accept_helper("1e/") == false);
    CHECK(accept_helper("1e:") == false);
    CHECK(accept_helper("1E.") == false);
    CHECK(accept_helper("1E/") == false);
    CHECK(accept_helper("1E:") == false);

    // unexpected end of null
    CHECK(accept_helper("n") == false);
    CHECK(accept_helper("nu") == false);
    CHECK(accept_helper("nul") == false);

    // unexpected end of true
    CHECK(accept_helper("t") == false);
    CHECK(accept_helper("tr") == false);
    CHECK(accept_helper("tru") == false);

    // unexpected end of false
    CHECK(accept_helper("f") == false);
    CHECK(accept_helper("fa") == false);
    CHECK(accept_helper("fal") == false);
    CHECK(accept_helper("fals") == false);

    // missing/unexpected end of array
    CHECK(accept_helper("[") == false);
    CHECK(accept_helper("[1") == false);
    CHECK(accept_helper("[1,") == false);
    CHECK(accept_helper("[1,]") == false);
    CHECK(accept_helper("]") == false);

    // missing/unexpected end of object
    CHECK(accept_helper("{") == false);
    CHECK(accept_helper("{\"foo\"") == false);
    CHECK(accept_helper("{\"foo\":") == false);
    CHECK(accept_helper("{\"foo\":}") == false);
    CHECK(accept_helper("{\"foo\":1,}") == false);
    CHECK(accept_helper("}") == false);

    // missing/unexpected end of string
    CHECK(accept_helper("\"") == false);
    CHECK(accept_helper("\"\\\"") == false);
    CHECK(accept_helper("\"\\u\"") == false);
    CHECK(accept_helper("\"\\u0\"") == false);
    CHECK(accept_helper("\"\\u01\"") == false);
    CHECK(accept_helper("\"\\u012\"") == false);
    CHECK(accept_helper("\"\\u") == false);
    CHECK(accept_helper("\"\\u0") == false);
    CHECK(accept_helper("\"\\u01") == false);
    CHECK(accept_helper("\"\\u012") == false);

    // unget of newline
    CHECK(parser_helper("\n123\n") == 123);

    // invalid escapes
    for (int c = 1; c < 128; ++c)
    {
        auto s = std::string("\"\\") + std::string(1, static_cast<char>(c)) + "\"";

        switch (c)
        {
            // valid escapes
            case ('"'):
            case ('\\'):
            case ('/'):
            case ('b'):
            case ('f'):
            case ('n'):
            case ('r'):
            case ('t'):
            {
                CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept());
                break;
            }

            // \u must be followed with four numbers, so we skip it here
            case ('u'):
            {
                break;
            }

            // any other combination of backslash and character is invalid
            default:
            {
                CHECK(json::parser(nlohmann::detail::input_adapter(s)).accept() == false);
                break;
            }
        }
    }

    // invalid \uxxxx escapes
    {
        // check whether character is a valid hex character
        const auto valid = [](int c)
        {
            switch (c)
            {
                case ('0'):
                case ('1'):
                case ('2'):
                case ('3'):
                case ('4'):
                case ('5'):
                case ('6'):
                case ('7'):
                case ('8'):
                case ('9'):
                case ('a'):
                case ('b'):
                case ('c'):
                case ('d'):
                case ('e'):
                case ('f'):
                case ('A'):
                case ('B'):
                case ('C'):
                case ('D'):
                case ('E'):
                case ('F'):
                {
                    return true;
                }

                default:
                {
                    return false;
                }
            }
        };

        for (int c = 1; c < 128; ++c)
        {
            std::string const s = "\"\\u";

            // create a string with the iterated character at each position
            const auto s1 = s + "000" + std::string(1, static_cast<char>(c)) + "\"";
            const auto s2 = s + "00" + std::string(1, static_cast<char>(c)) + "0\"";
            const auto s3 = s + "0" + std::string(1, static_cast<char>(c)) + "00\"";
            const auto s4 = s + std::string(1, static_cast<char>(c)) + "000\"";

            if (valid(c))
            {
                CAPTURE(s1)
                CHECK(json::parser(nlohmann::detail::input_adapter(s1)).accept());
                CAPTURE(s2)
                CHECK(json::parser(nlohmann::detail::input_adapter(s2)).accept());
                CAPTURE(s3)
                CHECK(json::parser(nlohmann::detail::input_adapter(s3)).accept());
                CAPTURE(s4)
                CHECK(json::parser(nlohmann::detail::input_adapter(s4)).accept());
            }
            else
            {
                CAPTURE(s1)
                CHECK(json::parser(nlohmann::detail::input_adapter(s1)).accept() == false);

                CAPTURE(s2)
                CHECK(json::parser(nlohmann::detail::input_adapter(s2)).accept() == false);

                CAPTURE(s3)
                CHECK(json::parser(nlohmann::detail::input_adapter(s3)).accept() == false);

                CAPTURE(s4)
                CHECK(json::parser(nlohmann::detail::input_adapter(s4)).accept() == false);
            }
        }
    }

    // missing part of a surrogate pair
    CHECK(accept_helper("\"\\uD80C\"") == false);
    // invalid surrogate pair
    CHECK(accept_helper("\"\\uD80C\\uD80C\"") == false);
    CHECK(accept_helper("\"\\uD80C\\u0000\"") == false);
    CHECK(accept_helper("\"\\uD80C\\uFFFF\"") == false);
}
  • cpp-test: [deserialization;contiguous containers;error cases] (tests/src/unit-deserialization.cpp)

SECTION("error cases")
{
    SECTION("case 1")
    {
        std::array<std::uint8_t, 9> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(10)"}));
    }

    SECTION("case 2")
    {
        std::array<std::uint8_t, 10> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(11)"}));
    }

    SECTION("case 3")
    {
        std::array<std::uint8_t, 17> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(18)"}));
    }

    SECTION("case 4")
    {
        std::array<std::uint8_t, 17> v = {{'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(18)"}));
    }

    SECTION("case 5")
    {
        std::array<std::uint8_t, 3> v = {{'\"', 0x7F, 0xC1}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(3)"}));
    }

    SECTION("case 6")
    {
        std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xDF, 0x7F}};
        json _;
        CHECK_THROWS_WITH_AS(_ = json::parse(std::begin(v), std::end(v)), "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"\x7f\xdf\x7f'", json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
    }

    SECTION("case 7")
    {
        std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xDF, 0xC0}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
    }

    SECTION("case 8")
    {
        std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xE0, 0x9F}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
    }

    SECTION("case 9")
    {
        std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xEF, 0xC0}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
    }

    SECTION("case 10")
    {
        std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xED, 0x7F}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
    }

    SECTION("case 11")
    {
        std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF0, 0x8F}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
    }

    SECTION("case 12")
    {
        std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF0, 0xC0}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
    }

    SECTION("case 13")
    {
        std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF3, 0x7F}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
    }

    SECTION("case 14")
    {
        std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF3, 0xC0}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
    }

    SECTION("case 15")
    {
        std::array<std::uint8_t, 4> v = {{'\"', 0x7F, 0xF4, 0x7F}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 1);
        CHECK(l.events == std::vector<std::string>({"parse_error(4)"}));
    }

    SECTION("case 16")
    {
        std::array<std::uint8_t, 6> v = {{'{', '\"', '\"', ':', '1', '1'}};
        json _;
        CHECK_THROWS_AS(_ = json::parse(std::begin(v), std::end(v)), json::parse_error&);
        CHECK(!json::accept(std::begin(v), std::end(v)));

        json j_error;
        CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
        CHECK(j_error.is_discarded());

        SaxEventLogger l;
        CHECK(!json::sax_parse(std::begin(v), std::end(v), &l));
        CHECK(l.events.size() == 4);
        CHECK(l.events == std::vector<std::string>(
        {
            "start_object()", "key()", "number_unsigned(11)",
            "parse_error(7)"
        }));
    }
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_string_no_quotes_with_bad_escape.json, /nst_json_testsuite2/test_parsing/n_string_single_doublequote.json, /nst_json_testsuite2/test_parsing/n_string_single_quote.json, /nst_json_testsuite2/test_parsing/n_string_single_string_no_double_quotes.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_no_quotes_with_bad_escape.json

    [\n]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_single_doublequote.json

    "
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_single_quote.json

    ['single quote']
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_single_string_no_double_quotes.json

    abc
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_no_quotes_with_bad_escape.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_single_doublequote.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_single_quote.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_single_string_no_double_quotes.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-07.3#

The service does not accept unescaped control characters.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;string;errors] (TSF/tests/unit-class_parser_core.cpp)

SECTION("errors")
{
    // error: tab in string
    CHECK(accept_helper("\"\t\"") == false);
    // error: newline in string
    CHECK(accept_helper("\"\n\"") == false);
    CHECK(accept_helper("\"\r\"") == false);
    // error: backspace in string
    CHECK(accept_helper("\"\b\"") == false);
    // improve code coverage
    CHECK(accept_helper("\uFF01") == false);
    CHECK(accept_helper("[-4:1,]") == false);
    // unescaped control characters
    CHECK(accept_helper("\"\x00\"") == false); // NOLINT(bugprone-string-literal-with-embedded-nul)
    CHECK(accept_helper("\"\x01\"") == false);
    CHECK(accept_helper("\"\x02\"") == false);
    CHECK(accept_helper("\"\x03\"") == false);
    CHECK(accept_helper("\"\x04\"") == false);
    CHECK(accept_helper("\"\x05\"") == false);
    CHECK(accept_helper("\"\x06\"") == false);
    CHECK(accept_helper("\"\x07\"") == false);
    CHECK(accept_helper("\"\x08\"") == false);
    CHECK(accept_helper("\"\x09\"") == false);
    CHECK(accept_helper("\"\x0a\"") == false);
    CHECK(accept_helper("\"\x0b\"") == false);
    CHECK(accept_helper("\"\x0c\"") == false);
    CHECK(accept_helper("\"\x0d\"") == false);
    CHECK(accept_helper("\"\x0e\"") == false);
    CHECK(accept_helper("\"\x0f\"") == false);
    CHECK(accept_helper("\"\x10\"") == false);
    CHECK(accept_helper("\"\x11\"") == false);
    CHECK(accept_helper("\"\x12\"") == false);
    CHECK(accept_helper("\"\x13\"") == false);
    CHECK(accept_helper("\"\x14\"") == false);
    CHECK(accept_helper("\"\x15\"") == false);
    CHECK(accept_helper("\"\x16\"") == false);
    CHECK(accept_helper("\"\x17\"") == false);
    CHECK(accept_helper("\"\x18\"") == false);
    CHECK(accept_helper("\"\x19\"") == false);
    CHECK(accept_helper("\"\x1a\"") == false);
    CHECK(accept_helper("\"\x1b\"") == false);
    CHECK(accept_helper("\"\x1c\"") == false);
    CHECK(accept_helper("\"\x1d\"") == false);
    CHECK(accept_helper("\"\x1e\"") == false);
    CHECK(accept_helper("\"\x1f\"") == false);
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-07.4#

The service does accept the escaped control characters.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;string;escaped] (TSF/tests/unit-class_parser_core.cpp)

SECTION("escaped")
{
    // quotation mark "\""
    auto r1 = R"("\"")"_json;
    CHECK(accept_helper("\"\\\"\""));
    // reverse solidus "\\"
    auto r2 = R"("\\")"_json;
    CHECK(accept_helper("\"\\\\\""));
    // solidus
    CHECK(accept_helper("\"\\/\""));
    // backspace
    CHECK(accept_helper("\"\\b\""));
    // formfeed
    CHECK(accept_helper("\"\\f\""));
    // newline
    CHECK(accept_helper("\"\\n\""));
    // carriage return
    CHECK(accept_helper("\"\\r\""));
    // horizontal tab
    CHECK(accept_helper("\"\\t\""));

    CHECK(accept_helper("\"\\u0001\""));
    CHECK(accept_helper("\"\\u000a\""));
    CHECK(accept_helper("\"\\u00b0\""));
    CHECK(accept_helper("\"\\u0c00\""));
    CHECK(accept_helper("\"\\ud000\""));
    CHECK(accept_helper("\"\\u000E\""));
    CHECK(accept_helper("\"\\u00F0\""));
    CHECK(accept_helper("\"\\u0100\""));
    CHECK(accept_helper("\"\\u2000\""));
    CHECK(accept_helper("\"\\uFFFF\""));
    CHECK(accept_helper("\"\\u20AC\""));
    CHECK(accept_helper("\"\""));
    CHECK(accept_helper("\"🎈\""));

    CHECK(accept_helper("\"\\ud80c\\udc60\""));
    CHECK(accept_helper("\"\\ud83c\\udf1e\""));
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json, /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pair.json, /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pairs.json, /nst_json_testsuite2/test_parsing/y_string_allowed_escapes.json, /nst_json_testsuite2/test_parsing/y_string_backslash_and_u_escaped_zero.json, /nst_json_testsuite2/test_parsing/y_string_backslash_doublequotes.json, /nst_json_testsuite2/test_parsing/y_string_comments.json, /nst_json_testsuite2/test_parsing/y_string_double_escape_a.json, /nst_json_testsuite2/test_parsing/y_string_double_escape_n.json, /nst_json_testsuite2/test_parsing/y_string_escaped_control_character.json, /nst_json_testsuite2/test_parsing/y_string_escaped_noncharacter.json]

    • Description: Checks that various escaped control and unicode characters are accepted.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json

    ["\u0060\u012a\u12AB"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pair.json

    ["\uD801\udc37"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pairs.json

    ["\ud83d\ude39\ud83d\udc8d"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_allowed_escapes.json

    ["\"\\\/\b\f\n\r\t"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_backslash_and_u_escaped_zero.json

    ["\\u0000"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_backslash_doublequotes.json

    ["\""]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_comments.json

    ["a/*b*/c/*d//e"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_double_escape_a.json

    ["\\a"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_double_escape_n.json

    ["\\n"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_escaped_control_character.json

    ["\u0012"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_escaped_noncharacter.json

    ["\uFFFF"]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pair.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pairs.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_allowed_escapes.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_backslash_and_u_escaped_zero.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_backslash_doublequotes.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_comments.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_double_escape_a.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_double_escape_n.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_escaped_control_character.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_escaped_noncharacter.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [Unicode (1/5);\\uxxxx sequences;correct sequences] (tests/src/unit-unicode1.cpp)

SECTION("correct sequences")
{
    // generate all UTF-8 code points; in total, 1112064 code points are
    // generated: 0x1FFFFF code points - 2048 invalid values between
    // 0xD800 and 0xDFFF.
    for (std::size_t cp = 0; cp <= 0x10FFFFu; ++cp)
    {
        // string to store the code point as in \uxxxx format
        std::string json_text = "\"";

        // decide whether to use one or two \uxxxx sequences
        if (cp < 0x10000u)
        {
            // The Unicode standard permanently reserves these code point
            // values for UTF-16 encoding of the high and low surrogates, and
            // they will never be assigned a character, so there should be no
            // reason to encode them. The official Unicode standard says that
            // no UTF forms, including UTF-16, can encode these code points.
            if (cp >= 0xD800u && cp <= 0xDFFFu)
            {
                // if we would not skip these code points, we would get a
                // "missing low surrogate" exception
                continue;
            }

            // code points in the Basic Multilingual Plane can be
            // represented with one \uxxxx sequence
            json_text += codepoint_to_unicode(cp);
        }
        else
        {
            // To escape an extended character that is not in the Basic
            // Multilingual Plane, the character is represented as a
            // 12-character sequence, encoding the UTF-16 surrogate pair
            const auto codepoint1 = 0xd800u + (((cp - 0x10000u) >> 10) & 0x3ffu);
            const auto codepoint2 = 0xdc00u + ((cp - 0x10000u) & 0x3ffu);
            json_text += codepoint_to_unicode(codepoint1) + codepoint_to_unicode(codepoint2);
        }

        json_text += "\"";
        CAPTURE(json_text)
        json _;
        CHECK_NOTHROW(_ = json::parse(json_text));
    }
}
  • cpp-test: [Unicode;escaped unicode] (TSF/tests/unit-strings.cpp)

SECTION("escaped unicode")
{
    for (uint32_t i = 0x0000; i<=0xFFFF; i++)
    {
        std::ostringstream temp;
        std::ostringstream temp2;
        temp << "\"\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << i << "\"";
        temp2 << "\"\\u" << std::hex << std::nouppercase << std::setfill('0') << std::setw(4) << i << "\"";
        if (i>=0xD800 && i<=0xDFFF)
        {
            // Unpaired utf-16 surrogates are illegal.
            // Observe that this verbatim not what RFC8259 §7 prescribes; 
            // it appears, however, to be in the spirit of RFC8259, cf. §8.2 
            // Illegal characters are not parsed anyway.
            CHECK(!json::accept(temp.str()));
            CHECK(!json::accept(temp2.str()));
            CHECK_THROWS_AS(parser_helper(temp.str()),json::parse_error&);
            CHECK_THROWS_AS(parser_helper(temp2.str()),json::parse_error&);
        } else { 
            // all other characters of the basic multilingual plane are accepted.
            CHECK(json::accept(temp.str()));
            CHECK(json::accept(temp2.str()));
            CHECK(json::parse(temp.str())==json::parse(temp2.str()));
        }
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-07.5#

The service accepts UTF-16 surrogate pairs.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;string;escaped] (TSF/tests/unit-class_parser_core.cpp)

SECTION("escaped")
{
    // quotation mark "\""
    auto r1 = R"("\"")"_json;
    CHECK(accept_helper("\"\\\"\""));
    // reverse solidus "\\"
    auto r2 = R"("\\")"_json;
    CHECK(accept_helper("\"\\\\\""));
    // solidus
    CHECK(accept_helper("\"\\/\""));
    // backspace
    CHECK(accept_helper("\"\\b\""));
    // formfeed
    CHECK(accept_helper("\"\\f\""));
    // newline
    CHECK(accept_helper("\"\\n\""));
    // carriage return
    CHECK(accept_helper("\"\\r\""));
    // horizontal tab
    CHECK(accept_helper("\"\\t\""));

    CHECK(accept_helper("\"\\u0001\""));
    CHECK(accept_helper("\"\\u000a\""));
    CHECK(accept_helper("\"\\u00b0\""));
    CHECK(accept_helper("\"\\u0c00\""));
    CHECK(accept_helper("\"\\ud000\""));
    CHECK(accept_helper("\"\\u000E\""));
    CHECK(accept_helper("\"\\u00F0\""));
    CHECK(accept_helper("\"\\u0100\""));
    CHECK(accept_helper("\"\\u2000\""));
    CHECK(accept_helper("\"\\uFFFF\""));
    CHECK(accept_helper("\"\\u20AC\""));
    CHECK(accept_helper("\"\""));
    CHECK(accept_helper("\"🎈\""));

    CHECK(accept_helper("\"\\ud80c\\udc60\""));
    CHECK(accept_helper("\"\\ud83c\\udf1e\""));
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pair.json, /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pairs.json]

    • Description: Checks that single and multiple surrogates are accepted.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pair.json

    ["\uD801\udc37"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pairs.json

    ["\ud83d\ude39\ud83d\udc8d"]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pair.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pairs.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [Unicode;escaped utf-16 surrogates;well-formed] (TSF/tests/unit-strings.cpp)

SECTION("well-formed")
{
    for (uint16_t i = 0xD800; i <= 0xDBFF; i++){
        for (uint16_t j = 0xD800; j <= 0xDFFF; j++){
            std::ostringstream temp;
            temp << "\"\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << i\
            << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << j\
            << "\"" ;
            if (j>=0xDC00){
                CHECK(json::accept(temp.str()));
                CHECK_NOTHROW(parser_helper(temp.str()));
            } else {
                CHECK(!json::accept(temp.str()));
                CHECK_THROWS_AS(parser_helper(temp.str()),json::parse_error&);
            }
        }
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-07.6#

The service does accept the non-empty strings.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json, /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pair.json, /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pairs.json, /nst_json_testsuite2/test_parsing/y_string_allowed_escapes.json, /nst_json_testsuite2/test_parsing/y_string_backslash_and_u_escaped_zero.json, /nst_json_testsuite2/test_parsing/y_string_backslash_doublequotes.json, /nst_json_testsuite2/test_parsing/y_string_comments.json, /nst_json_testsuite2/test_parsing/y_string_double_escape_a.json, /nst_json_testsuite2/test_parsing/y_string_double_escape_n.json, /nst_json_testsuite2/test_parsing/y_string_escaped_control_character.json, /nst_json_testsuite2/test_parsing/y_string_escaped_noncharacter.json, /nst_json_testsuite2/test_parsing/y_string_in_array.json, /nst_json_testsuite2/test_parsing/y_string_in_array_with_leading_space.json, /nst_json_testsuite2/test_parsing/y_string_last_surrogates_1_and_2.json, /nst_json_testsuite2/test_parsing/y_string_nbsp_uescaped.json, /nst_json_testsuite2/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json, /nst_json_testsuite2/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json, /nst_json_testsuite2/test_parsing/y_string_null_escape.json, /nst_json_testsuite2/test_parsing/y_string_one-byte-utf-8.json, /nst_json_testsuite2/test_parsing/y_string_pi.json, /nst_json_testsuite2/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json, /nst_json_testsuite2/test_parsing/y_string_simple_ascii.json, /nst_json_testsuite2/test_parsing/y_string_space.json, /nst_json_testsuite2/test_parsing/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json, /nst_json_testsuite2/test_parsing/y_string_three-byte-utf-8.json, /nst_json_testsuite2/test_parsing/y_string_two-byte-utf-8.json, /nst_json_testsuite2/test_parsing/y_string_u+2028_line_sep.json, /nst_json_testsuite2/test_parsing/y_string_u+2029_par_sep.json, /nst_json_testsuite2/test_parsing/y_string_uEscape.json, /nst_json_testsuite2/test_parsing/y_string_uescaped_newline.json, /nst_json_testsuite2/test_parsing/y_string_unescaped_char_delete.json, /nst_json_testsuite2/test_parsing/y_string_unicode.json, /nst_json_testsuite2/test_parsing/y_string_unicodeEscapedBackslash.json, /nst_json_testsuite2/test_parsing/y_string_unicode_2.json, /nst_json_testsuite2/test_parsing/y_string_unicode_U+10FFFE_nonchar.json, /nst_json_testsuite2/test_parsing/y_string_unicode_U+1FFFE_nonchar.json, /nst_json_testsuite2/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json, /nst_json_testsuite2/test_parsing/y_string_unicode_U+2064_invisible_plus.json, /nst_json_testsuite2/test_parsing/y_string_unicode_U+FDD0_nonchar.json, /nst_json_testsuite2/test_parsing/y_string_unicode_U+FFFE_nonchar.json, /nst_json_testsuite2/test_parsing/y_string_unicode_escaped_double_quote.json, /nst_json_testsuite2/test_parsing/y_string_utf8.json, /nst_json_testsuite2/test_parsing/y_string_with_del_character.json, /nst_json_testsuite2/test_parsing/y_structure_lonely_string.json]

    • Description: Checks that various non-empty valid strings are accepted.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json

    ["\u0060\u012a\u12AB"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pair.json

    ["\uD801\udc37"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pairs.json

    ["\ud83d\ude39\ud83d\udc8d"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_allowed_escapes.json

    ["\"\\\/\b\f\n\r\t"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_backslash_and_u_escaped_zero.json

    ["\\u0000"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_backslash_doublequotes.json

    ["\""]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_comments.json

    ["a/*b*/c/*d//e"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_double_escape_a.json

    ["\\a"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_double_escape_n.json

    ["\\n"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_escaped_control_character.json

    ["\u0012"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_escaped_noncharacter.json

    ["\uFFFF"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_in_array.json

    ["asd"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_in_array_with_leading_space.json

    [ "asd"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_last_surrogates_1_and_2.json

    ["\uDBFF\uDFFF"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_nbsp_uescaped.json

    ["new\u00A0line"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json

    ["􏿿"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json

    ["￿"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_null_escape.json

    ["\u0000"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_one-byte-utf-8.json

    ["\u002c"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_pi.json

    ["π"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json

    ["𛿿"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_simple_ascii.json

    ["asd "]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_space.json

    " "
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json

    ["\uD834\uDd1e"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_three-byte-utf-8.json

    ["\u0821"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_two-byte-utf-8.json

    ["\u0123"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_u+2028_line_sep.json

    ["
		"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_u+2029_par_sep.json

    ["
		"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_uEscape.json

    ["\u0061\u30af\u30EA\u30b9"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_uescaped_newline.json

    ["new\u000Aline"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unescaped_char_delete.json

    [""]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unicode.json

    ["\uA66D"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unicodeEscapedBackslash.json

    ["\u005C"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unicode_2.json

    ["⍂㈴⍂"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unicode_U+10FFFE_nonchar.json

    ["\uDBFF\uDFFE"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unicode_U+1FFFE_nonchar.json

    ["\uD83F\uDFFE"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json

    ["\u200B"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unicode_U+2064_invisible_plus.json

    ["\u2064"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unicode_U+FDD0_nonchar.json

    ["\uFDD0"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unicode_U+FFFE_nonchar.json

    ["\uFFFE"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_unicode_escaped_double_quote.json

    ["\u0022"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_utf8.json

    ["€𝄞"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_string_with_del_character.json

    ["aa"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_structure_lonely_string.json

    "asd"
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pair.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_accepted_surrogate_pairs.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_allowed_escapes.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_backslash_and_u_escaped_zero.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_backslash_doublequotes.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_comments.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_double_escape_a.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_double_escape_n.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_escaped_control_character.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_escaped_noncharacter.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_in_array.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_in_array_with_leading_space.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_last_surrogates_1_and_2.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_nbsp_uescaped.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_null_escape.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_one-byte-utf-8.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_pi.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_simple_ascii.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_space.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_three-byte-utf-8.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_two-byte-utf-8.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_u+2028_line_sep.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_u+2029_par_sep.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_uEscape.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_uescaped_newline.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unescaped_char_delete.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unicode.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unicodeEscapedBackslash.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unicode_2.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unicode_U+10FFFE_nonchar.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unicode_U+1FFFE_nonchar.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unicode_U+2064_invisible_plus.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unicode_U+FDD0_nonchar.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unicode_U+FFFE_nonchar.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_unicode_escaped_double_quote.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_utf8.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_string_with_del_character.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_structure_lonely_string.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-07.7#

The service does not accept escaped invalid characters.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape.json, /nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u.json, /nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u1.json, /nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u1x.json, /nst_json_testsuite2/test_parsing/n_string_accentuated_char_no_quotes.json, /nst_json_testsuite2/test_parsing/n_string_backslash_00.json, /nst_json_testsuite2/test_parsing/n_string_escape_x.json, /nst_json_testsuite2/test_parsing/n_string_escaped_backslash_bad.json, /nst_json_testsuite2/test_parsing/n_string_escaped_ctrl_char_tab.json, /nst_json_testsuite2/test_parsing/n_string_escaped_emoji.json, /nst_json_testsuite2/test_parsing/n_string_incomplete_escape.json, /nst_json_testsuite2/test_parsing/n_string_incomplete_escaped_character.json, /nst_json_testsuite2/test_parsing/n_string_incomplete_surrogate.json, /nst_json_testsuite2/test_parsing/n_string_incomplete_surrogate_escape_invalid.json, /nst_json_testsuite2/test_parsing/n_string_invalid-utf-8-in-escape.json, /nst_json_testsuite2/test_parsing/n_string_invalid_backslash_esc.json, /nst_json_testsuite2/test_parsing/n_string_invalid_unicode_escape.json, /nst_json_testsuite2/test_parsing/n_string_invalid_utf8_after_escape.json]

    • Description: Checks that various illegal control characters and utf-8 characters are rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape.json

    ["\uD800\"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u.json

    ["\uD800\u"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u1.json

    ["\uD800\u1"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u1x.json

    ["\uD800\u1x"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_accentuated_char_no_quotes.json

    [é]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_backslash_00.json

    ["\�"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_escape_x.json

    ["\x00"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_escaped_backslash_bad.json

    ["\\\"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_escaped_ctrl_char_tab.json

    ["\	"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_escaped_emoji.json

    ["\🌀"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_incomplete_escape.json

    ["\"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_incomplete_escaped_character.json

    ["\u00A"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_incomplete_surrogate.json

    ["\uD834\uDd"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_incomplete_surrogate_escape_invalid.json

    ["\uD800\uD800\x"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_invalid-utf-8-in-escape.json

    ["\uﮒ"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_invalid_backslash_esc.json

    ["\a"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_invalid_unicode_escape.json

    ["\uqqqq"]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_string_invalid_utf8_after_escape.json

    ["\ﮒ"]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u1.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_1_surrogate_then_escape_u1x.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_accentuated_char_no_quotes.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_backslash_00.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_escape_x.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_escaped_backslash_bad.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_escaped_ctrl_char_tab.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_escaped_emoji.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_incomplete_escape.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_incomplete_escaped_character.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_incomplete_surrogate.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_incomplete_surrogate_escape_invalid.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_invalid-utf-8-in-escape.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_invalid_backslash_esc.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_invalid_unicode_escape.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_string_invalid_utf8_after_escape.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [Unicode;escaped unicode] (TSF/tests/unit-strings.cpp)

SECTION("escaped unicode")
{
    for (uint32_t i = 0x0000; i<=0xFFFF; i++)
    {
        std::ostringstream temp;
        std::ostringstream temp2;
        temp << "\"\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << i << "\"";
        temp2 << "\"\\u" << std::hex << std::nouppercase << std::setfill('0') << std::setw(4) << i << "\"";
        if (i>=0xD800 && i<=0xDFFF)
        {
            // Unpaired utf-16 surrogates are illegal.
            // Observe that this verbatim not what RFC8259 §7 prescribes; 
            // it appears, however, to be in the spirit of RFC8259, cf. §8.2 
            // Illegal characters are not parsed anyway.
            CHECK(!json::accept(temp.str()));
            CHECK(!json::accept(temp2.str()));
            CHECK_THROWS_AS(parser_helper(temp.str()),json::parse_error&);
            CHECK_THROWS_AS(parser_helper(temp2.str()),json::parse_error&);
        } else { 
            // all other characters of the basic multilingual plane are accepted.
            CHECK(json::accept(temp.str()));
            CHECK(json::accept(temp2.str()));
            CHECK(json::parse(temp.str())==json::parse(temp2.str()));
        }
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-07.8#

The service does not accept single unpaired utf-16 surrogates.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [Unicode;escaped unicode] (TSF/tests/unit-strings.cpp)

SECTION("escaped unicode")
{
    for (uint32_t i = 0x0000; i<=0xFFFF; i++)
    {
        std::ostringstream temp;
        std::ostringstream temp2;
        temp << "\"\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << i << "\"";
        temp2 << "\"\\u" << std::hex << std::nouppercase << std::setfill('0') << std::setw(4) << i << "\"";
        if (i>=0xD800 && i<=0xDFFF)
        {
            // Unpaired utf-16 surrogates are illegal.
            // Observe that this verbatim not what RFC8259 §7 prescribes; 
            // it appears, however, to be in the spirit of RFC8259, cf. §8.2 
            // Illegal characters are not parsed anyway.
            CHECK(!json::accept(temp.str()));
            CHECK(!json::accept(temp2.str()));
            CHECK_THROWS_AS(parser_helper(temp.str()),json::parse_error&);
            CHECK_THROWS_AS(parser_helper(temp2.str()),json::parse_error&);
        } else { 
            // all other characters of the basic multilingual plane are accepted.
            CHECK(json::accept(temp.str()));
            CHECK(json::accept(temp2.str()));
            CHECK(json::parse(temp.str())==json::parse(temp2.str()));
        }
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-07.9#

The service does not accept unescaped UTF-16 surrogate pairs.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [Unicode;unescaped unicode] (TSF/tests/unit-strings.cpp)

SECTION("unescaped unicode")
{
    for (uint32_t i = 0x0000; i<=0x10FFFF; i++)
    {
        std::string temp = uint_to_utf8(i);
        if ((i>=0xD800 && i<=0xDFFF)) { 
            // Unpaired utf-16 surrogates are illegal.
            // Observe that this verbatim not what RFC8259 §7 prescribes; 
            // it appears, however, to be in the spirit of RFC8259, cf. §8.2 
            // The other characters are illegal if unescaped.
            CHECK(!json::accept(temp));
            CHECK_THROWS_AS(parser_helper(temp),json::parse_error&);
            if (i<=0xDBFF){
                for (uint32_t j = 0xDC00; j<=0xDFFF; j++){
                    temp += uint_to_utf8(j);
                    CHECK(!json::accept(temp));
                    CHECK_THROWS_AS(parser_helper(temp),json::parse_error&);
                }
            } 
        } else if (i<0x0020||i==0x0022||i==0x005c){
            CHECK(!json::accept(temp));
            CHECK_THROWS_AS(parser_helper(temp),json::parse_error&);
        } else {
            // All other characters are valid according to RFC8259
            CHECK_NOTHROW(parser_helper(temp));
        }
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-08#

The service accepts numbers according to RFC8259 §6.

Supported Requests:

Supporting Items:

References:

  • function: [lexer::scan_number] (include/nlohmann/detail/input/lexer.hpp)

    • Description: function, which scans numbers and verifies en passant that these number is in accordance with RFC8259

    token_type scan_number()  // lgtm [cpp/use-of-goto] `goto` is used in this function to implement the number-parsing state machine described above. By design, any finite input will eventually reach the "done" state or return token_type::parse_error. In each intermediate state, 1 byte of the input is appended to the token_buffer vector, and only the already initialized variables token_buffer, number_type, and error_message are manipulated.
    {
        // reset token_buffer to store the number's bytes
        reset();

        // the type of the parsed number; initially set to unsigned; will be
        // changed if minus sign, decimal point or exponent is read
        token_type number_type = token_type::value_unsigned;

        // state (init): we just found out we need to scan a number
        switch (current)
        {
            case '-':
            {
                add(current);
                goto scan_number_minus;
            }

            case '0':
            {
                add(current);
                goto scan_number_zero;
            }

            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            {
                add(current);
                goto scan_number_any1;
            }

            // all other characters are rejected outside scan_number()
            default:            // LCOV_EXCL_LINE
                JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
        }

scan_number_minus:
        // state: we just parsed a leading minus sign
        number_type = token_type::value_integer;
        switch (get())
        {
            case '0':
            {
                add(current);
                goto scan_number_zero;
            }

            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            {
                add(current);
                goto scan_number_any1;
            }

            default:
            {
                error_message = "invalid number; expected digit after '-'";
                return token_type::parse_error;
            }
        }

scan_number_zero:
        // state: we just parse a zero (maybe with a leading minus sign)
        switch (get())
        {
            case '.':
            {
                add(decimal_point_char);
                decimal_point_position = token_buffer.size() - 1;
                goto scan_number_decimal1;
            }

            case 'e':
            case 'E':
            {
                add(current);
                goto scan_number_exponent;
            }

            default:
                goto scan_number_done;
        }

scan_number_any1:
        // state: we just parsed a number 0-9 (maybe with a leading minus sign)
        switch (get())
        {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            {
                add(current);
                goto scan_number_any1;
            }

            case '.':
            {
                add(decimal_point_char);
                decimal_point_position = token_buffer.size() - 1;
                goto scan_number_decimal1;
            }

            case 'e':
            case 'E':
            {
                add(current);
                goto scan_number_exponent;
            }

            default:
                goto scan_number_done;
        }

scan_number_decimal1:
        // state: we just parsed a decimal point
        number_type = token_type::value_float;
        switch (get())
        {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            {
                add(current);
                goto scan_number_decimal2;
            }

            default:
            {
                error_message = "invalid number; expected digit after '.'";
                return token_type::parse_error;
            }
        }

scan_number_decimal2:
        // we just parsed at least one number after a decimal point
        switch (get())
        {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            {
                add(current);
                goto scan_number_decimal2;
            }

            case 'e':
            case 'E':
            {
                add(current);
                goto scan_number_exponent;
            }

            default:
                goto scan_number_done;
        }

scan_number_exponent:
        // we just parsed an exponent
        number_type = token_type::value_float;
        switch (get())
        {
            case '+':
            case '-':
            {
                add(current);
                goto scan_number_sign;
            }

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            {
                add(current);
                goto scan_number_any2;
            }

            default:
            {
                error_message =
                    "invalid number; expected '+', '-', or digit after exponent";
                return token_type::parse_error;
            }
        }

scan_number_sign:
        // we just parsed an exponent sign
        switch (get())
        {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            {
                add(current);
                goto scan_number_any2;
            }

            default:
            {
                error_message = "invalid number; expected digit after exponent sign";
                return token_type::parse_error;
            }
        }

scan_number_any2:
        // we just parsed a number after the exponent or exponent sign
        switch (get())
        {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            {
                add(current);
                goto scan_number_any2;
            }

            default:
                goto scan_number_done;
        }

scan_number_done:
        // unget the character after the number (we only read it to know that
        // we are done scanning a number)
        unget();

        char* endptr = nullptr; // NOLINT(misc-const-correctness,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
        errno = 0;

        // try to parse integers first and fall back to floats
        if (number_type == token_type::value_unsigned)
        {
            const auto x = std::strtoull(token_buffer.data(), &endptr, 10);

            // we checked the number format before
            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());

            if (errno != ERANGE)
            {
                value_unsigned = static_cast<number_unsigned_t>(x);
                if (value_unsigned == x)
                {
                    return token_type::value_unsigned;
                }
            }
        }
        else if (number_type == token_type::value_integer)
        {
            const auto x = std::strtoll(token_buffer.data(), &endptr, 10);

            // we checked the number format before
            JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());

            if (errno != ERANGE)
            {
                value_integer = static_cast<number_integer_t>(x);
                if (value_integer == x)
                {
                    return token_type::value_integer;
                }
            }
        }

        // this code is reached if we parse a floating-point number or if an
        // integer conversion above failed
        strtof(value_float, token_buffer.data(), &endptr);

        // we checked the number format before
        JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());

        return token_type::value_float;
    }

Fallacies:

None

Graph:

No Historic Data Found


NJF-08.1#

The service does accept integers within the limits of 64-bit double.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;number;integers] (TSF/tests/unit-class_parser_core.cpp)

SECTION("integers")
{
    SECTION("without exponent")
    {
        CHECK(accept_helper("-128"));
        CHECK(accept_helper("-0"));
        CHECK(accept_helper("0"));
        CHECK(accept_helper("128"));
    }

    SECTION("with exponent")
    {
        CHECK(accept_helper("0e1"));
        CHECK(accept_helper("0E1"));

        CHECK(accept_helper("10000E-4"));
        CHECK(accept_helper("10000E-3"));
        CHECK(accept_helper("10000E-2"));
        CHECK(accept_helper("10000E-1"));
        CHECK(accept_helper("10000E0"));
        CHECK(accept_helper("10000E1"));
        CHECK(accept_helper("10000E2"));
        CHECK(accept_helper("10000E3"));
        CHECK(accept_helper("10000E4"));

        CHECK(accept_helper("10000e-4"));
        CHECK(accept_helper("10000e-3"));
        CHECK(accept_helper("10000e-2"));
        CHECK(accept_helper("10000e-1"));
        CHECK(accept_helper("10000e0"));
        CHECK(accept_helper("10000e1"));
        CHECK(accept_helper("10000e2"));
        CHECK(accept_helper("10000e3"));
        CHECK(accept_helper("10000e4"));

        CHECK(accept_helper("-0e1"));
        CHECK(accept_helper("-0E1"));
        CHECK(accept_helper("-0E123"));
    }

    SECTION("edge cases")
    {
        // From RFC8259, Section 6:
        // Note that when such software is used, numbers that are
        // integers and are in the range [-(2**53)+1, (2**53)-1]
        // are interoperable in the sense that implementations will
        // agree exactly on their numeric values.

        // -(2**53)+1
        CHECK(accept_helper("-9007199254740991"));
        // (2**53)-1
        CHECK(accept_helper("9007199254740991"));
    }

    SECTION("over the edge cases")  // issue #178 - Integer conversion to unsigned (incorrect handling of 64-bit integers)
    {
        // While RFC8259, Section 6 specifies a preference for support
        // for ranges in range of IEEE 754-2008 binary64 (double precision)
        // this does not accommodate 64 bit integers without loss of accuracy.
        // As 64 bit integers are now widely used in software, it is desirable
        // to expand support to the full 64 bit (signed and unsigned) range
        // i.e. -(2**63) -> (2**64)-1.

        // -(2**63)    ** Note: compilers see negative literals as negated positive numbers (hence the -1))
        CHECK(accept_helper("-9223372036854775808"));
        // (2**63)-1
        CHECK(accept_helper("9223372036854775807"));
        // (2**64)-1
        CHECK(accept_helper("18446744073709551615"));
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-08.2#

The service does accept integers according to IEEE 754 binary64.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;number;integers;edge cases] (TSF/tests/unit-class_parser_core.cpp)

SECTION("edge cases")
{
    // From RFC8259, Section 6:
    // Note that when such software is used, numbers that are
    // integers and are in the range [-(2**53)+1, (2**53)-1]
    // are interoperable in the sense that implementations will
    // agree exactly on their numeric values.

    // -(2**53)+1
    CHECK(accept_helper("-9007199254740991"));
    // (2**53)-1
    CHECK(accept_helper("9007199254740991"));
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-08.3#

The service does not accept NaN, infinity.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_number_+Inf.json, /nst_json_testsuite2/test_parsing/n_number_-NaN.json, /nst_json_testsuite2/test_parsing/n_number_Inf.json, /nst_json_testsuite2/test_parsing/n_number_NaN.json, /nst_json_testsuite2/test_parsing/n_number_NaN.json]

    • Description: Checks that NaN and Inf are rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_+Inf.json

    [+Inf]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_-NaN.json

    [-NaN]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_Inf.json

    [Inf]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_NaN.json

    [NaN]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_NaN.json

    [NaN]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_+Inf.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_-NaN.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_Inf.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_NaN.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [accept;illegal literal numbers] (TSF/tests/unit-literals.cpp)

SECTION("illegal literal numbers")
{
    SECTION("inf")
    {
        CHECK(!json::accept("inf"));
        CHECK(!json::accept("Inf"));
        CHECK(!json::accept("iNf"));
        CHECK(!json::accept("INf"));
        CHECK(!json::accept("inF"));
        CHECK(!json::accept("InF"));
        CHECK(!json::accept("iNF"));
        CHECK(!json::accept("INF"));
    }
    SECTION("infinity")
    {
        CHECK(!json::accept("infinity"));
        CHECK(!json::accept("Infinity"));
        CHECK(!json::accept("iNfinity"));
        CHECK(!json::accept("INfinity"));
        CHECK(!json::accept("inFinity"));
        CHECK(!json::accept("InFinity"));
        CHECK(!json::accept("iNFinity"));
        CHECK(!json::accept("INFinity"));
        CHECK(!json::accept("infInity"));
        CHECK(!json::accept("InfInity"));
        CHECK(!json::accept("iNfInity"));
        CHECK(!json::accept("INfInity"));
        CHECK(!json::accept("inFInity"));
        CHECK(!json::accept("InFInity"));
        CHECK(!json::accept("iNFInity"));
        CHECK(!json::accept("INFInity"));
        CHECK(!json::accept("infiNity"));
        CHECK(!json::accept("InfiNity"));
        CHECK(!json::accept("iNfiNity"));
        CHECK(!json::accept("INfiNity"));
        CHECK(!json::accept("inFiNity"));
        CHECK(!json::accept("InFiNity"));
        CHECK(!json::accept("iNFiNity"));
        CHECK(!json::accept("INFiNity"));
        CHECK(!json::accept("infINity"));
        CHECK(!json::accept("InfINity"));
        CHECK(!json::accept("iNfINity"));
        CHECK(!json::accept("INfINity"));
        CHECK(!json::accept("inFINity"));
        CHECK(!json::accept("InFINity"));
        CHECK(!json::accept("iNFINity"));
        CHECK(!json::accept("INFINity"));
        CHECK(!json::accept("infinIty"));
        CHECK(!json::accept("InfinIty"));
        CHECK(!json::accept("iNfinIty"));
        CHECK(!json::accept("INfinIty"));
        CHECK(!json::accept("inFinIty"));
        CHECK(!json::accept("InFinIty"));
        CHECK(!json::accept("iNFinIty"));
        CHECK(!json::accept("INFinIty"));
        CHECK(!json::accept("infInIty"));
        CHECK(!json::accept("InfInIty"));
        CHECK(!json::accept("iNfInIty"));
        CHECK(!json::accept("INfInIty"));
        CHECK(!json::accept("inFInIty"));
        CHECK(!json::accept("InFInIty"));
        CHECK(!json::accept("iNFInIty"));
        CHECK(!json::accept("INFInIty"));
        CHECK(!json::accept("infiNIty"));
        CHECK(!json::accept("InfiNIty"));
        CHECK(!json::accept("iNfiNIty"));
        CHECK(!json::accept("INfiNIty"));
        CHECK(!json::accept("inFiNIty"));
        CHECK(!json::accept("InFiNIty"));
        CHECK(!json::accept("iNFiNIty"));
        CHECK(!json::accept("INFiNIty"));
        CHECK(!json::accept("infINIty"));
        CHECK(!json::accept("InfINIty"));
        CHECK(!json::accept("iNfINIty"));
        CHECK(!json::accept("INfINIty"));
        CHECK(!json::accept("inFINIty"));
        CHECK(!json::accept("InFINIty"));
        CHECK(!json::accept("iNFINIty"));
        CHECK(!json::accept("INFINIty"));
        CHECK(!json::accept("infiniTy"));
        CHECK(!json::accept("InfiniTy"));
        CHECK(!json::accept("iNfiniTy"));
        CHECK(!json::accept("INfiniTy"));
        CHECK(!json::accept("inFiniTy"));
        CHECK(!json::accept("InFiniTy"));
        CHECK(!json::accept("iNFiniTy"));
        CHECK(!json::accept("INFiniTy"));
        CHECK(!json::accept("infIniTy"));
        CHECK(!json::accept("InfIniTy"));
        CHECK(!json::accept("iNfIniTy"));
        CHECK(!json::accept("INfIniTy"));
        CHECK(!json::accept("inFIniTy"));
        CHECK(!json::accept("InFIniTy"));
        CHECK(!json::accept("iNFIniTy"));
        CHECK(!json::accept("INFIniTy"));
        CHECK(!json::accept("infiNiTy"));
        CHECK(!json::accept("InfiNiTy"));
        CHECK(!json::accept("iNfiNiTy"));
        CHECK(!json::accept("INfiNiTy"));
        CHECK(!json::accept("inFiNiTy"));
        CHECK(!json::accept("InFiNiTy"));
        CHECK(!json::accept("iNFiNiTy"));
        CHECK(!json::accept("INFiNiTy"));
        CHECK(!json::accept("infINiTy"));
        CHECK(!json::accept("InfINiTy"));
        CHECK(!json::accept("iNfINiTy"));
        CHECK(!json::accept("INfINiTy"));
        CHECK(!json::accept("inFINiTy"));
        CHECK(!json::accept("InFINiTy"));
        CHECK(!json::accept("iNFINiTy"));
        CHECK(!json::accept("INFINiTy"));
        CHECK(!json::accept("infinITy"));
        CHECK(!json::accept("InfinITy"));
        CHECK(!json::accept("iNfinITy"));
        CHECK(!json::accept("INfinITy"));
        CHECK(!json::accept("inFinITy"));
        CHECK(!json::accept("InFinITy"));
        CHECK(!json::accept("iNFinITy"));
        CHECK(!json::accept("INFinITy"));
        CHECK(!json::accept("infInITy"));
        CHECK(!json::accept("InfInITy"));
        CHECK(!json::accept("iNfInITy"));
        CHECK(!json::accept("INfInITy"));
        CHECK(!json::accept("inFInITy"));
        CHECK(!json::accept("InFInITy"));
        CHECK(!json::accept("iNFInITy"));
        CHECK(!json::accept("INFInITy"));
        CHECK(!json::accept("infiNITy"));
        CHECK(!json::accept("InfiNITy"));
        CHECK(!json::accept("iNfiNITy"));
        CHECK(!json::accept("INfiNITy"));
        CHECK(!json::accept("inFiNITy"));
        CHECK(!json::accept("InFiNITy"));
        CHECK(!json::accept("iNFiNITy"));
        CHECK(!json::accept("INFiNITy"));
        CHECK(!json::accept("infINITy"));
        CHECK(!json::accept("InfINITy"));
        CHECK(!json::accept("iNfINITy"));
        CHECK(!json::accept("INfINITy"));
        CHECK(!json::accept("inFINITy"));
        CHECK(!json::accept("InFINITy"));
        CHECK(!json::accept("iNFINITy"));
        CHECK(!json::accept("INFINITy"));
        CHECK(!json::accept("infinitY"));
        CHECK(!json::accept("InfinitY"));
        CHECK(!json::accept("iNfinitY"));
        CHECK(!json::accept("INfinitY"));
        CHECK(!json::accept("inFinitY"));
        CHECK(!json::accept("InFinitY"));
        CHECK(!json::accept("iNFinitY"));
        CHECK(!json::accept("INFinitY"));
        CHECK(!json::accept("infInitY"));
        CHECK(!json::accept("InfInitY"));
        CHECK(!json::accept("iNfInitY"));
        CHECK(!json::accept("INfInitY"));
        CHECK(!json::accept("inFInitY"));
        CHECK(!json::accept("InFInitY"));
        CHECK(!json::accept("iNFInitY"));
        CHECK(!json::accept("INFInitY"));
        CHECK(!json::accept("infiNitY"));
        CHECK(!json::accept("InfiNitY"));
        CHECK(!json::accept("iNfiNitY"));
        CHECK(!json::accept("INfiNitY"));
        CHECK(!json::accept("inFiNitY"));
        CHECK(!json::accept("InFiNitY"));
        CHECK(!json::accept("iNFiNitY"));
        CHECK(!json::accept("INFiNitY"));
        CHECK(!json::accept("infINitY"));
        CHECK(!json::accept("InfINitY"));
        CHECK(!json::accept("iNfINitY"));
        CHECK(!json::accept("INfINitY"));
        CHECK(!json::accept("inFINitY"));
        CHECK(!json::accept("InFINitY"));
        CHECK(!json::accept("iNFINitY"));
        CHECK(!json::accept("INFINitY"));
        CHECK(!json::accept("infinItY"));
        CHECK(!json::accept("InfinItY"));
        CHECK(!json::accept("iNfinItY"));
        CHECK(!json::accept("INfinItY"));
        CHECK(!json::accept("inFinItY"));
        CHECK(!json::accept("InFinItY"));
        CHECK(!json::accept("iNFinItY"));
        CHECK(!json::accept("INFinItY"));
        CHECK(!json::accept("infInItY"));
        CHECK(!json::accept("InfInItY"));
        CHECK(!json::accept("iNfInItY"));
        CHECK(!json::accept("INfInItY"));
        CHECK(!json::accept("inFInItY"));
        CHECK(!json::accept("InFInItY"));
        CHECK(!json::accept("iNFInItY"));
        CHECK(!json::accept("INFInItY"));
        CHECK(!json::accept("infiNItY"));
        CHECK(!json::accept("InfiNItY"));
        CHECK(!json::accept("iNfiNItY"));
        CHECK(!json::accept("INfiNItY"));
        CHECK(!json::accept("inFiNItY"));
        CHECK(!json::accept("InFiNItY"));
        CHECK(!json::accept("iNFiNItY"));
        CHECK(!json::accept("INFiNItY"));
        CHECK(!json::accept("infINItY"));
        CHECK(!json::accept("InfINItY"));
        CHECK(!json::accept("iNfINItY"));
        CHECK(!json::accept("INfINItY"));
        CHECK(!json::accept("inFINItY"));
        CHECK(!json::accept("InFINItY"));
        CHECK(!json::accept("iNFINItY"));
        CHECK(!json::accept("INFINItY"));
        CHECK(!json::accept("infiniTY"));
        CHECK(!json::accept("InfiniTY"));
        CHECK(!json::accept("iNfiniTY"));
        CHECK(!json::accept("INfiniTY"));
        CHECK(!json::accept("inFiniTY"));
        CHECK(!json::accept("InFiniTY"));
        CHECK(!json::accept("iNFiniTY"));
        CHECK(!json::accept("INFiniTY"));
        CHECK(!json::accept("infIniTY"));
        CHECK(!json::accept("InfIniTY"));
        CHECK(!json::accept("iNfIniTY"));
        CHECK(!json::accept("INfIniTY"));
        CHECK(!json::accept("inFIniTY"));
        CHECK(!json::accept("InFIniTY"));
        CHECK(!json::accept("iNFIniTY"));
        CHECK(!json::accept("INFIniTY"));
        CHECK(!json::accept("infiNiTY"));
        CHECK(!json::accept("InfiNiTY"));
        CHECK(!json::accept("iNfiNiTY"));
        CHECK(!json::accept("INfiNiTY"));
        CHECK(!json::accept("inFiNiTY"));
        CHECK(!json::accept("InFiNiTY"));
        CHECK(!json::accept("iNFiNiTY"));
        CHECK(!json::accept("INFiNiTY"));
        CHECK(!json::accept("infINiTY"));
        CHECK(!json::accept("InfINiTY"));
        CHECK(!json::accept("iNfINiTY"));
        CHECK(!json::accept("INfINiTY"));
        CHECK(!json::accept("inFINiTY"));
        CHECK(!json::accept("InFINiTY"));
        CHECK(!json::accept("iNFINiTY"));
        CHECK(!json::accept("INFINiTY"));
        CHECK(!json::accept("infinITY"));
        CHECK(!json::accept("InfinITY"));
        CHECK(!json::accept("iNfinITY"));
        CHECK(!json::accept("INfinITY"));
        CHECK(!json::accept("inFinITY"));
        CHECK(!json::accept("InFinITY"));
        CHECK(!json::accept("iNFinITY"));
        CHECK(!json::accept("INFinITY"));
        CHECK(!json::accept("infInITY"));
        CHECK(!json::accept("InfInITY"));
        CHECK(!json::accept("iNfInITY"));
        CHECK(!json::accept("INfInITY"));
        CHECK(!json::accept("inFInITY"));
        CHECK(!json::accept("InFInITY"));
        CHECK(!json::accept("iNFInITY"));
        CHECK(!json::accept("INFInITY"));
        CHECK(!json::accept("infiNITY"));
        CHECK(!json::accept("InfiNITY"));
        CHECK(!json::accept("iNfiNITY"));
        CHECK(!json::accept("INfiNITY"));
        CHECK(!json::accept("inFiNITY"));
        CHECK(!json::accept("InFiNITY"));
        CHECK(!json::accept("iNFiNITY"));
        CHECK(!json::accept("INFiNITY"));
        CHECK(!json::accept("infINITY"));
        CHECK(!json::accept("InfINITY"));
        CHECK(!json::accept("iNfINITY"));
        CHECK(!json::accept("INfINITY"));
        CHECK(!json::accept("inFINITY"));
        CHECK(!json::accept("InFINITY"));
        CHECK(!json::accept("iNFINITY"));
        CHECK(!json::accept("INFINITY"));
    }
    SECTION("NaN")
    {
        CHECK(!json::accept("nan"));
        CHECK(!json::accept("Nan"));
        CHECK(!json::accept("nAn"));
        CHECK(!json::accept("NAn"));
        CHECK(!json::accept("naN"));
        CHECK(!json::accept("NaN"));
        CHECK(!json::accept("nAN"));
        CHECK(!json::accept("NAN"));
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-08.4#

The service does accept e or E for numbers with exponent within the bounds of double.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;number;integers;with exponent] (TSF/tests/unit-class_parser_core.cpp)

SECTION("with exponent")
{
    CHECK(accept_helper("0e1"));
    CHECK(accept_helper("0E1"));

    CHECK(accept_helper("10000E-4"));
    CHECK(accept_helper("10000E-3"));
    CHECK(accept_helper("10000E-2"));
    CHECK(accept_helper("10000E-1"));
    CHECK(accept_helper("10000E0"));
    CHECK(accept_helper("10000E1"));
    CHECK(accept_helper("10000E2"));
    CHECK(accept_helper("10000E3"));
    CHECK(accept_helper("10000E4"));

    CHECK(accept_helper("10000e-4"));
    CHECK(accept_helper("10000e-3"));
    CHECK(accept_helper("10000e-2"));
    CHECK(accept_helper("10000e-1"));
    CHECK(accept_helper("10000e0"));
    CHECK(accept_helper("10000e1"));
    CHECK(accept_helper("10000e2"));
    CHECK(accept_helper("10000e3"));
    CHECK(accept_helper("10000e4"));

    CHECK(accept_helper("-0e1"));
    CHECK(accept_helper("-0E1"));
    CHECK(accept_helper("-0E123"));
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/y_number_real_capital_e.json, /nst_json_testsuite2/test_parsing/y_number_real_capital_e_neg_exp.json, /nst_json_testsuite2/test_parsing/y_number_real_capital_e_pos_exp.json, /nst_json_testsuite2/test_parsing/y_number_real_exponent.json, /nst_json_testsuite2/test_parsing/y_number_real_fraction_exponent.json, /nst_json_testsuite2/test_parsing/y_number_real_neg_exp.json, /nst_json_testsuite2/test_parsing/y_number_real_pos_exponent.json]

    • Description: Checks that various numbers with exponent are accepted.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_number_real_capital_e.json

    [1E22]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_number_real_capital_e_neg_exp.json

    [1E-2]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_number_real_capital_e_pos_exp.json

    [1E+2]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_number_real_exponent.json

    [123e45]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_number_real_fraction_exponent.json

    [123.456e78]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_number_real_neg_exp.json

    [1e-2]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/y_number_real_pos_exponent.json

    [1e+2]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;y] (tests/src/unit-testsuites.cpp)

    SECTION("y")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_number_real_capital_e.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_number_real_capital_e_neg_exp.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_number_real_capital_e_pos_exp.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_number_real_exponent.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_number_real_fraction_exponent.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_number_real_neg_exp.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/y_number_real_pos_exponent.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_NOTHROW(_ = json::parse(f));
            std::ifstream f2(filename);
            CHECK(json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    

Fallacies:

None

Graph:

No Historic Data Found


NJF-08.5#

The service does not accept u0415 and u0436 (cyrillic e and E) as exponent signs in numbers with exponent.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [accept;exponents;U+0425] (TSF/tests/unit-numbers.cpp)

SECTION("U+0425")
{            
    CHECK(!json::accept("0\u0425123"));
    CHECK(!json::accept("123\u04250"));
    CHECK(!json::accept("0.123\u0425123"));
    CHECK(!json::accept("1.23\u0425123"));
    CHECK(!json::accept("1.23\u04250"));
}
  • cpp-test: [accept;exponents;U+0436] (TSF/tests/unit-numbers.cpp)

SECTION("U+0436")
{            
    CHECK(!json::accept("0\u0436123"));
    CHECK(!json::accept("123\u04360"));
    CHECK(!json::accept("0.123\u0436123"));
    CHECK(!json::accept("1.23\u0436123"));
    CHECK(!json::accept("1.23\u04360"));
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-08.6#

The service does not accept invalid syntax for numbers.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;number;invalid numbers] (TSF/tests/unit-class_parser_core.cpp)

SECTION("invalid numbers")
{
    CHECK(accept_helper("01") == false);
    CHECK(accept_helper("--1") == false);
    CHECK(accept_helper("1.") == false);
    CHECK(accept_helper("1E") == false);
    CHECK(accept_helper("1E-") == false);
    CHECK(accept_helper("1.E1") == false);
    CHECK(accept_helper("-1E") == false);
    CHECK(accept_helper("-0E#") == false);
    CHECK(accept_helper("-0E-#") == false);
    CHECK(accept_helper("-0#") == false);
    CHECK(accept_helper("-0.0:") == false);
    CHECK(accept_helper("-0.0Z") == false);
    CHECK(accept_helper("-0E123:") == false);
    CHECK(accept_helper("-0e0-:") == false);
    CHECK(accept_helper("-0e-:") == false);
    CHECK(accept_helper("-0f") == false);

    // numbers must not begin with "+"
    CHECK(accept_helper("+1") == false);
    CHECK(accept_helper("+0") == false);
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_number_++.json, /nst_json_testsuite2/test_parsing/n_number_+1.json, /nst_json_testsuite2/test_parsing/n_number_+Inf.json, /nst_json_testsuite2/test_parsing/n_number_-01.json, /nst_json_testsuite2/test_parsing/n_number_-1.0..json, /nst_json_testsuite2/test_parsing/n_number_-2..json, /nst_json_testsuite2/test_parsing/n_number_-NaN.json, /nst_json_testsuite2/test_parsing/n_number_.-1.json, /nst_json_testsuite2/test_parsing/n_number_.2e-3.json, /nst_json_testsuite2/test_parsing/n_number_0.1.2.json, /nst_json_testsuite2/test_parsing/n_number_0.3e+.json, /nst_json_testsuite2/test_parsing/n_number_0.3e.json, /nst_json_testsuite2/test_parsing/n_number_0.e1.json, /nst_json_testsuite2/test_parsing/n_number_0_capital_E+.json, /nst_json_testsuite2/test_parsing/n_number_0_capital_E.json, /nst_json_testsuite2/test_parsing/n_number_0e+.json, /nst_json_testsuite2/test_parsing/n_number_0e.json, /nst_json_testsuite2/test_parsing/n_number_1.0e+.json, /nst_json_testsuite2/test_parsing/n_number_1.0e-.json, /nst_json_testsuite2/test_parsing/n_number_1.0e.json, /nst_json_testsuite2/test_parsing/n_number_1_000.json, /nst_json_testsuite2/test_parsing/n_number_1eE2.json, /nst_json_testsuite2/test_parsing/n_number_2.e+3.json, /nst_json_testsuite2/test_parsing/n_number_2.e-3.json, /nst_json_testsuite2/test_parsing/n_number_2.e3.json, /nst_json_testsuite2/test_parsing/n_number_9.e+.json, /nst_json_testsuite2/test_parsing/n_number_Inf.json, /nst_json_testsuite2/test_parsing/n_number_NaN.json, /nst_json_testsuite2/test_parsing/n_number_U+FF11_fullwidth_digit_one.json, /nst_json_testsuite2/test_parsing/n_number_expression.json, /nst_json_testsuite2/test_parsing/n_number_hex_1_digit.json, /nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json, /nst_json_testsuite2/test_parsing/n_number_infinity.json, /nst_json_testsuite2/test_parsing/n_number_invalid+-.json, /nst_json_testsuite2/test_parsing/n_number_invalid-negative-real.json, /nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-bigger-int.json, /nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-exponent.json, /nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-int.json, /nst_json_testsuite2/test_parsing/n_number_minus_infinity.json, /nst_json_testsuite2/test_parsing/n_number_minus_sign_with_trailing_garbage.json, /nst_json_testsuite2/test_parsing/n_number_minus_space_1.json, /nst_json_testsuite2/test_parsing/n_number_neg_int_starting_with_zero.json, /nst_json_testsuite2/test_parsing/n_number_neg_real_without_int_part.json, /nst_json_testsuite2/test_parsing/n_number_neg_with_garbage_at_end.json, /nst_json_testsuite2/test_parsing/n_number_real_garbage_after_e.json, /nst_json_testsuite2/test_parsing/n_number_real_with_invalid_utf8_after_e.json, /nst_json_testsuite2/test_parsing/n_number_real_without_fractional_part.json, /nst_json_testsuite2/test_parsing/n_number_starting_with_dot.json, /nst_json_testsuite2/test_parsing/n_number_with_alpha.json, /nst_json_testsuite2/test_parsing/n_number_with_alpha_char.json, /nst_json_testsuite2/test_parsing/n_number_with_leading_zero.json]

    • Description: Tests whether various numbers with invalid syntax according to RFC8259 are rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_++.json

    [++1234]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_+1.json

    [+1]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_+Inf.json

    [+Inf]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_-01.json

    [-01]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_-1.0..json

    [-1.0.]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_-2..json

    [-2.]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_-NaN.json

    [-NaN]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_.-1.json

    [.-1]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_.2e-3.json

    [.2e-3]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_0.1.2.json

    [0.1.2]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_0.3e+.json

    [0.3e+]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_0.3e.json

    [0.3e]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_0.e1.json

    [0.e1]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_0_capital_E+.json

    [0E+]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_0_capital_E.json

    [0E]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_0e+.json

    [0e+]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_0e.json

    [0e]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_1.0e+.json

    [1.0e+]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_1.0e-.json

    [1.0e-]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_1.0e.json

    [1.0e]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_1_000.json

    [1 000.0]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_1eE2.json

    [1eE2]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_2.e+3.json

    [2.e+3]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_2.e-3.json

    [2.e-3]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_2.e3.json

    [2.e3]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_9.e+.json

    [9.e+]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_Inf.json

    [Inf]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_NaN.json

    [NaN]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_U+FF11_fullwidth_digit_one.json

    []
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_expression.json

    [1+2]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_hex_1_digit.json

    [0x1]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json

    [0x42]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_infinity.json

    [Infinity]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_invalid+-.json

    [0e+-1]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_invalid-negative-real.json

    [-123.123foo]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-bigger-int.json

    [123
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-exponent.json

    ㅛㅥ工
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-int.json

    [0
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_minus_infinity.json

    [-Infinity]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_minus_sign_with_trailing_garbage.json

    [-foo]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_minus_space_1.json

    [- 1]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_neg_int_starting_with_zero.json

    [-012]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_neg_real_without_int_part.json

    [-.123]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_neg_with_garbage_at_end.json

    [-1x]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_real_garbage_after_e.json

    [1ea]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_real_with_invalid_utf8_after_e.json

    [1e
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_real_without_fractional_part.json

    [1.]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_starting_with_dot.json

    [.123]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_with_alpha.json

    [1.2a-3]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_with_alpha_char.json

    [1.8011670033376514H-308]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_with_leading_zero.json

    [012]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_++.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_+1.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_+Inf.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_-01.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_-1.0..json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_-2..json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_-NaN.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_.-1.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_.2e-3.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0.1.2.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0.3e+.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0.3e.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0.e1.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0_capital_E+.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0_capital_E.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0e+.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_0e.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_1.0e+.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_1.0e-.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_1.0e.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_1_000.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_1eE2.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_2.e+3.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_2.e-3.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_2.e3.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_9.e+.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_Inf.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_NaN.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_U+FF11_fullwidth_digit_one.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_expression.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_hex_1_digit.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_infinity.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_invalid+-.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_invalid-negative-real.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-bigger-int.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-exponent.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_invalid-utf-8-in-int.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_minus_infinity.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_minus_sign_with_trailing_garbage.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_minus_space_1.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_neg_int_starting_with_zero.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_neg_real_without_int_part.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_neg_with_garbage_at_end.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_real_garbage_after_e.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_real_with_invalid_utf8_after_e.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_real_without_fractional_part.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_starting_with_dot.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_with_alpha.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_with_alpha_char.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_with_leading_zero.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [accept;operators] (TSF/tests/unit-numbers.cpp)

SECTION("operators")
{
    SECTION("plus")
    {
        CHECK(!json::accept("1+1"));
        CHECK(!json::accept("0.1+1"));
        CHECK(!json::accept("0.1+1.0"));
        CHECK(!json::accept("0+0.1"));
        CHECK(!json::accept("0.1\u00452+1"));
        CHECK(!json::accept("0.1\u00652+1"));
        CHECK(!json::accept("1+0.1\u00652"));
        CHECK(!json::accept("3.5+0.1\u00652"));
    }
    SECTION("minus")
    {

        CHECK(!json::accept("1-1"));
        CHECK(!json::accept("0.1-1"));
        CHECK(!json::accept("0.1-1.0"));
        CHECK(!json::accept("0-0.1"));
        CHECK(!json::accept("0.1\u00452-1"));
        CHECK(!json::accept("0.1\u00652-1"));
        CHECK(!json::accept("1-0.1\u00652"));
        CHECK(!json::accept("3.5-0.1\u00652"));
    }
    SECTION("brackets")
    {

        CHECK(!json::accept("(145)"));
        CHECK(!json::accept("(34.32874)"));
        CHECK(!json::accept("42\u0045(134)"));
        CHECK(!json::accept("42\u0065(134)"));
    }
    SECTION("factorial")
    {

        CHECK(!json::accept("13!"));
    }
    SECTION("multiplication")
    {

        CHECK(!json::accept("1*1"));
        CHECK(!json::accept("1.45*5"));
        CHECK(!json::accept("154*23.76"));
        CHECK(!json::accept("1\u004545*3"));
        CHECK(!json::accept("1\u006545*3"));
        CHECK(!json::accept("3*6\u004512"));
        CHECK(!json::accept("3*6\u006512"));
    }
    SECTION("division")
    {

        CHECK(!json::accept("0/0"));
        CHECK(!json::accept("1.45/5"));
        CHECK(!json::accept("154/23.76"));
        CHECK(!json::accept("1\u004545/3"));
        CHECK(!json::accept("1\u006545/3"));
        CHECK(!json::accept("7/6\u004512"));
        CHECK(!json::accept("7/6\u006512"));
    }
    SECTION("comma")
    {

        CHECK(!json::accept("0,0"));
        CHECK(!json::accept("100,000"));
        CHECK(!json::accept("1,000.23"));
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-08.7#

The service does accept decimal points in numbers within the bounds of double.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;number;floating-point] (TSF/tests/unit-class_parser_core.cpp)

SECTION("floating-point")
{
    SECTION("without exponent")
    {
        CHECK(accept_helper("-128.5"));
        CHECK(accept_helper("0.999"));
        CHECK(accept_helper("128.5"));
        CHECK(accept_helper("-0.0"));
    }

    SECTION("with exponent")
    {
        CHECK(accept_helper("-128.5E3"));
        CHECK(accept_helper("-128.5E-3"));
        CHECK(accept_helper("-0.0e1"));
        CHECK(accept_helper("-0.0E1"));
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-08.8#

The service does not accept leading zeroes.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_number_-01.json, /nst_json_testsuite2/test_parsing/n_number_neg_int_starting_with_zero.json]

    • Description: Checks that -01 is rejected.

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_-01.json

    [-01]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_neg_int_starting_with_zero.json

    [-012]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_-01.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_neg_int_starting_with_zero.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [parser class - core;accept;number;invalid numbers] (TSF/tests/unit-class_parser_core.cpp)

SECTION("invalid numbers")
{
    CHECK(accept_helper("01") == false);
    CHECK(accept_helper("--1") == false);
    CHECK(accept_helper("1.") == false);
    CHECK(accept_helper("1E") == false);
    CHECK(accept_helper("1E-") == false);
    CHECK(accept_helper("1.E1") == false);
    CHECK(accept_helper("-1E") == false);
    CHECK(accept_helper("-0E#") == false);
    CHECK(accept_helper("-0E-#") == false);
    CHECK(accept_helper("-0#") == false);
    CHECK(accept_helper("-0.0:") == false);
    CHECK(accept_helper("-0.0Z") == false);
    CHECK(accept_helper("-0E123:") == false);
    CHECK(accept_helper("-0e0-:") == false);
    CHECK(accept_helper("-0e-:") == false);
    CHECK(accept_helper("-0f") == false);

    // numbers must not begin with "+"
    CHECK(accept_helper("+1") == false);
    CHECK(accept_helper("+0") == false);
}
  • cpp-test: [accept;Leading zeroes] (TSF/tests/unit-numbers.cpp)

SECTION("Leading zeroes")
{
    CHECK(!json::accept("01.0"));
    CHECK(!json::accept("05\u004542"));
    CHECK(!json::accept("05\u006542"));
    CHECK(!json::accept("00"));
    CHECK(!json::accept("000000000000000000000000000000000000000000000000"));
    CHECK(!json::accept("0000000000000000000000000000000000042"));
    CHECK(!json::accept("-01.0"));
    CHECK(!json::accept("-05\u004542"));
    CHECK(!json::accept("-05\u006542"));
    CHECK(!json::accept("-00"));
    CHECK(!json::accept("-000000000000000000000000000000000000000000000000"));
    CHECK(!json::accept("-0000000000000000000000000000000000042"));
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-08.9#

The service does not accept any other digit symbol than 0-9.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [parser class - core;accept;number;integers] (TSF/tests/unit-class_parser_core.cpp)

SECTION("integers")
{
    SECTION("without exponent")
    {
        CHECK(accept_helper("-128"));
        CHECK(accept_helper("-0"));
        CHECK(accept_helper("0"));
        CHECK(accept_helper("128"));
    }

    SECTION("with exponent")
    {
        CHECK(accept_helper("0e1"));
        CHECK(accept_helper("0E1"));

        CHECK(accept_helper("10000E-4"));
        CHECK(accept_helper("10000E-3"));
        CHECK(accept_helper("10000E-2"));
        CHECK(accept_helper("10000E-1"));
        CHECK(accept_helper("10000E0"));
        CHECK(accept_helper("10000E1"));
        CHECK(accept_helper("10000E2"));
        CHECK(accept_helper("10000E3"));
        CHECK(accept_helper("10000E4"));

        CHECK(accept_helper("10000e-4"));
        CHECK(accept_helper("10000e-3"));
        CHECK(accept_helper("10000e-2"));
        CHECK(accept_helper("10000e-1"));
        CHECK(accept_helper("10000e0"));
        CHECK(accept_helper("10000e1"));
        CHECK(accept_helper("10000e2"));
        CHECK(accept_helper("10000e3"));
        CHECK(accept_helper("10000e4"));

        CHECK(accept_helper("-0e1"));
        CHECK(accept_helper("-0E1"));
        CHECK(accept_helper("-0E123"));
    }

    SECTION("edge cases")
    {
        // From RFC8259, Section 6:
        // Note that when such software is used, numbers that are
        // integers and are in the range [-(2**53)+1, (2**53)-1]
        // are interoperable in the sense that implementations will
        // agree exactly on their numeric values.

        // -(2**53)+1
        CHECK(accept_helper("-9007199254740991"));
        // (2**53)-1
        CHECK(accept_helper("9007199254740991"));
    }

    SECTION("over the edge cases")  // issue #178 - Integer conversion to unsigned (incorrect handling of 64-bit integers)
    {
        // While RFC8259, Section 6 specifies a preference for support
        // for ranges in range of IEEE 754-2008 binary64 (double precision)
        // this does not accommodate 64 bit integers without loss of accuracy.
        // As 64 bit integers are now widely used in software, it is desirable
        // to expand support to the full 64 bit (signed and unsigned) range
        // i.e. -(2**63) -> (2**64)-1.

        // -(2**63)    ** Note: compilers see negative literals as negated positive numbers (hence the -1))
        CHECK(accept_helper("-9223372036854775808"));
        // (2**63)-1
        CHECK(accept_helper("9223372036854775807"));
        // (2**64)-1
        CHECK(accept_helper("18446744073709551615"));
    }
}
  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_number_hex_1_digit.json, /nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json, /nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json]

    • Description: Rejects Hexadecimals

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_hex_1_digit.json

    [0x1]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json

    [0x42]
    
    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json

    [0x42]
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_hex_1_digit.json",
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [accept;bases] (TSF/tests/unit-numbers.cpp)

SECTION("bases")
{
    SECTION("Octal")
    {
        CHECK(!json::accept("o42"));
        CHECK(!json::accept("q42"));
        CHECK(!json::accept("0o42"));
        CHECK(!json::accept("\\42"));
        CHECK(!json::accept("@42"));
        CHECK(!json::accept("&42"));
        CHECK(!json::accept("$42"));
        CHECK(!json::accept("42o"));
    }
    // Recall that hexadecimal is also checked in nst_json_testsuite2/test_parsing/n_number_hex_1_digit.json
    // and nst_json_testsuite2/test_parsing/n_number_hex_2_digits.json
    SECTION("Hexadecimal")
    {
        CHECK(!json::accept("0x42"));
        CHECK(!json::accept("42h"));
        CHECK(!json::accept("42H"));
        CHECK(!json::accept("0F42h"));
        CHECK(!json::accept("0F42H"));
        CHECK(!json::accept("$4A2"));
        CHECK(!json::accept("16r42"));
        CHECK(!json::accept("0h42"));
        CHECK(!json::accept("#42"));
        CHECK(!json::accept("#16r42"));
        CHECK(!json::accept("42F3"));
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-12#

The service decodes UTF-8 data.

Supported Requests:

Supporting Items:

References:

None

Fallacies:

None

Graph:

No Historic Data Found


NJF-12.1#

The service rejects malformed UTF-8 data.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [accept;malformed sequences] (TSF/tests/unit-strings.cpp)

SECTION("malformed sequences")
{
    SECTION("Unexpected continuation bytes")
    {
        // Each unexpected continuation byte should be separately signalled as a
        // malformed sequence of its own.

        // 3.1.1  First continuation byte 0x80
        CHECK(!json::accept("\"\x80\""));
        // 3.1.2  Last  continuation byte 0xbf
        CHECK(!json::accept("\"\xbf\""));

        // 3.1.3  2 continuation bytes
        CHECK(!json::accept("\"\x80\xbf\""));
        // 3.1.4  3 continuation bytes
        CHECK(!json::accept("\"\x80\xbf\x80\""));
        // 3.1.5  4 continuation bytes
        CHECK(!json::accept("\"\x80\xbf\x80\xbf\""));
        // 3.1.6  5 continuation bytes
        CHECK(!json::accept("\"\x80\xbf\x80\xbf\x80\""));
        // 3.1.7  6 continuation bytes
        CHECK(!json::accept("\"\x80\xbf\x80\xbf\x80\xbf\""));
        // 3.1.8  7 continuation bytes
        CHECK(!json::accept("\"\x80\xbf\x80\xbf\x80\xbf\x80\""));

        // 3.1.9  Sequence of all 64 possible continuation bytes (0x80-0xbf)
        CHECK(!json::accept("\"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\""));
    }

    SECTION("Lonely start characters")
    {
        // 3.2.1  All 32 first bytes of 2-byte sequences (0xc0-0xdf)
        CHECK(!json::accept("\"\xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf\""));
        // 3.2.2  All 16 first bytes of 3-byte sequences (0xe0-0xef)
        CHECK(!json::accept("\"\xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef\""));
        // 3.2.3  All 8 first bytes of 4-byte sequences (0xf0-0xf7)
        CHECK(!json::accept("\"\xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7\""));
        // 3.2.4  All 4 first bytes of 5-byte sequences (0xf8-0xfb)
        CHECK(!json::accept("\"\xf8 \xf9 \xfa \xfb\""));
        // 3.2.5  All 2 first bytes of 6-byte sequences (0xfc-0xfd)
        CHECK(!json::accept("\"\xfc \xfd\""));
    }

    SECTION("Sequences with last continuation byte missing")
    {
        // All bytes of an incomplete sequence should be signalled as a single
        // malformed sequence, i.e., you should see only a single replacement
        // character in each of the next 10 tests. (Characters as in section 2)

        // 3.3.1  2-byte sequence with last byte missing (U+0000)
        CHECK(!json::accept("\"\xc0\""));
        // 3.3.2  3-byte sequence with last byte missing (U+0000)
        CHECK(!json::accept("\"\xe0\x80\""));
        // 3.3.3  4-byte sequence with last byte missing (U+0000)
        CHECK(!json::accept("\"\xf0\x80\x80\""));
        // 3.3.4  5-byte sequence with last byte missing (U+0000)
        CHECK(!json::accept("\"\xf8\x80\x80\x80\""));
        // 3.3.5  6-byte sequence with last byte missing (U+0000)
        CHECK(!json::accept("\"\xfc\x80\x80\x80\x80\""));
        // 3.3.6  2-byte sequence with last byte missing (U-000007FF)
        CHECK(!json::accept("\"\xdf\""));
        // 3.3.7  3-byte sequence with last byte missing (U-0000FFFF)
        CHECK(!json::accept("\"\xef\xbf\""));
        // 3.3.8  4-byte sequence with last byte missing (U-001FFFFF)
        CHECK(!json::accept("\"\xf7\xbf\xbf\""));
        // 3.3.9  5-byte sequence with last byte missing (U-03FFFFFF)
        CHECK(!json::accept("\"\xfb\xbf\xbf\xbf\""));
        // 3.3.10 6-byte sequence with last byte missing (U-7FFFFFFF)
        CHECK(!json::accept("\"\xfd\xbf\xbf\xbf\xbf\""));
    }

    SECTION("Concatenation of incomplete sequences")
    {
        // All the 10 sequences of 3.3 concatenated, you should see 10 malformed
        // sequences being signalled:
        CHECK(!json::accept("\"\xc0\xe0\x80\xf0\x80\x80\xf8\x80\x80\x80\xfc\x80\x80\x80\x80\xdf\xef\xbf\xf7\xbf\xbf\xfb\xbf\xbf\xbf\xfd\xbf\xbf\xbf\xbf\""));
    }

    SECTION("Impossible bytes")
    {
        // The following two bytes cannot appear in a correct UTF-8 string

        // 3.5.1  fe
        CHECK(!json::accept("\"\xfe\""));
        // 3.5.2  ff
        CHECK(!json::accept("\"\xff\""));
        // 3.5.3  fe fe ff ff
        CHECK(!json::accept("\"\xfe\xfe\xff\xff\""));
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-12.2#

The service rejects “overlong sequences”.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [accept;overlong sequences] (TSF/tests/unit-strings.cpp)

SECTION("overlong sequences")
{
    SECTION("Examples of an overlong ASCII character")
    {
        // 4.1.1 U+002F = c0 af
        CHECK(!json::accept("\"\xc0\xaf\""));
        // 4.1.2 U+002F = e0 80 af
        CHECK(!json::accept("\"\xe0\x80\xaf\""));
        // 4.1.3 U+002F = f0 80 80 af
        CHECK(!json::accept("\"\xf0\x80\x80\xaf\""));
        // 4.1.4 U+002F = f8 80 80 80 af
        CHECK(!json::accept("\"\xf8\x80\x80\x80\xaf\""));
        // 4.1.5 U+002F = fc 80 80 80 80 af
        CHECK(!json::accept("\"\xfc\x80\x80\x80\x80\xaf\""));
    }

    SECTION("Maximum overlong sequences")
    {
        // Below you see the highest Unicode value that is still resulting in an
        // overlong sequence if represented with the given number of bytes. This
        // is a boundary test for safe UTF-8 decoders. All five characters should
        // be rejected like malformed UTF-8 sequences.

        // 4.2.1  U-0000007F = c1 bf
        CHECK(!json::accept("\"\xc1\xbf\""));
        // 4.2.2  U-000007FF = e0 9f bf
        CHECK(!json::accept("\"\xe0\x9f\xbf\""));
        // 4.2.3  U-0000FFFF = f0 8f bf bf
        CHECK(!json::accept("\"\xf0\x8f\xbf\xbf\""));
        // 4.2.4  U-001FFFFF = f8 87 bf bf bf
        CHECK(!json::accept("\"\xf8\x87\xbf\xbf\xbf\""));
        // 4.2.5  U-03FFFFFF = fc 83 bf bf bf bf
        CHECK(!json::accept("\"\xfc\x83\xbf\xbf\xbf\xbf\""));
    }

    SECTION("Overlong representation of the NUL character")
    {
        // The following five sequences should also be rejected like malformed
        // UTF-8 sequences and should not be treated like the ASCII NUL
        // character.

        // 4.3.1  U+0000 = c0 80
        CHECK(!json::accept("\"\xc0\x80\""));
        // 4.3.2  U+0000 = e0 80 80
        CHECK(!json::accept("\"\xe0\x80\x80\""));
        // 4.3.3  U+0000 = f0 80 80 80
        CHECK(!json::accept("\"\xf0\x80\x80\x80\""));
        // 4.3.4  U+0000 = f8 80 80 80 80
        CHECK(!json::accept("\"\xf8\x80\x80\x80\x80\""));
        // 4.3.5  U+0000 = fc 80 80 80 80 80
        CHECK(!json::accept("\"\xfc\x80\x80\x80\x80\x80\""));
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-12.3#

The service rejects single escaped and unescaped, and paired unescaped utf-16 surrogates.

Supported Requests:

Supporting Items:

None

References:

  • cpp-testsuite: [/nst_json_testsuite2/test_parsing/n_structure_lone-invalid-utf-8.json]

    • JSON Testsuite: /nst_json_testsuite2/test_parsing/n_structure_lone-invalid-utf-8.json

    V
    
    • cpp-test: [nst’s JSONTestSuite (2);test_parsing;n] (tests/src/unit-testsuites.cpp)

    SECTION("n")
    {
        for (const auto* filename :
                {
                    TEST_DATA_DIRECTORY "/nst_json_testsuite2/test_parsing/n_structure_lone-invalid-utf-8.json",
                }
            )
        {
            CAPTURE(filename)
            std::ifstream f(filename);
            json _;
            CHECK_THROWS_AS(_ = json::parse(f), json::parse_error&);
            std::ifstream f2(filename);
            CHECK(!json::accept(f2));
        }
    }
    
    
     // Note: Other test data lines have been filtered out for conciseness.
    
  • cpp-test: [Unicode;unescaped unicode] (TSF/tests/unit-strings.cpp)

SECTION("unescaped unicode")
{
    for (uint32_t i = 0x0000; i<=0x10FFFF; i++)
    {
        std::string temp = uint_to_utf8(i);
        if ((i>=0xD800 && i<=0xDFFF)) { 
            // Unpaired utf-16 surrogates are illegal.
            // Observe that this verbatim not what RFC8259 §7 prescribes; 
            // it appears, however, to be in the spirit of RFC8259, cf. §8.2 
            // The other characters are illegal if unescaped.
            CHECK(!json::accept(temp));
            CHECK_THROWS_AS(parser_helper(temp),json::parse_error&);
            if (i<=0xDBFF){
                for (uint32_t j = 0xDC00; j<=0xDFFF; j++){
                    temp += uint_to_utf8(j);
                    CHECK(!json::accept(temp));
                    CHECK_THROWS_AS(parser_helper(temp),json::parse_error&);
                }
            } 
        } else if (i<0x0020||i==0x0022||i==0x005c){
            CHECK(!json::accept(temp));
            CHECK_THROWS_AS(parser_helper(temp),json::parse_error&);
        } else {
            // All other characters are valid according to RFC8259
            CHECK_NOTHROW(parser_helper(temp));
        }
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-12.5#

The service accepts Non-Characters.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [accept;noncharacter code positions] (TSF/tests/unit-strings.cpp)

SECTION("noncharacter code positions")
{
    // 5.3.1  U+FFFE = ef bf be
    CHECK(json::accept("\"\xef\xbf\xbe\""));
    // 5.3.2  U+FFFF = ef bf bf
    CHECK(json::accept("\"\xef\xbf\xbf\""));

    // 5.3.3  U+FDD0 .. U+FDEF
    CHECK(json::accept("\"\xEF\xB7\x90\""));
    CHECK(json::accept("\"\xEF\xB7\x91\""));
    CHECK(json::accept("\"\xEF\xB7\x92\""));
    CHECK(json::accept("\"\xEF\xB7\x93\""));
    CHECK(json::accept("\"\xEF\xB7\x94\""));
    CHECK(json::accept("\"\xEF\xB7\x95\""));
    CHECK(json::accept("\"\xEF\xB7\x96\""));
    CHECK(json::accept("\"\xEF\xB7\x97\""));
    CHECK(json::accept("\"\xEF\xB7\x98\""));
    CHECK(json::accept("\"\xEF\xB7\x99\""));
    CHECK(json::accept("\"\xEF\xB7\x9A\""));
    CHECK(json::accept("\"\xEF\xB7\x9B\""));
    CHECK(json::accept("\"\xEF\xB7\x9C\""));
    CHECK(json::accept("\"\xEF\xB7\x9D\""));
    CHECK(json::accept("\"\xEF\xB7\x9E\""));
    CHECK(json::accept("\"\xEF\xB7\x9F\""));
    CHECK(json::accept("\"\xEF\xB7\xA0\""));
    CHECK(json::accept("\"\xEF\xB7\xA1\""));
    CHECK(json::accept("\"\xEF\xB7\xA2\""));
    CHECK(json::accept("\"\xEF\xB7\xA3\""));
    CHECK(json::accept("\"\xEF\xB7\xA4\""));
    CHECK(json::accept("\"\xEF\xB7\xA5\""));
    CHECK(json::accept("\"\xEF\xB7\xA6\""));
    CHECK(json::accept("\"\xEF\xB7\xA7\""));
    CHECK(json::accept("\"\xEF\xB7\xA8\""));
    CHECK(json::accept("\"\xEF\xB7\xA9\""));
    CHECK(json::accept("\"\xEF\xB7\xAA\""));
    CHECK(json::accept("\"\xEF\xB7\xAB\""));
    CHECK(json::accept("\"\xEF\xB7\xAC\""));
    CHECK(json::accept("\"\xEF\xB7\xAD\""));
    CHECK(json::accept("\"\xEF\xB7\xAE\""));
    CHECK(json::accept("\"\xEF\xB7\xAF\""));

    // 5.3.4  U+nFFFE U+nFFFF (for n = 1..10)
    CHECK(json::accept("\"\xF0\x9F\xBF\xBF\""));
    CHECK(json::accept("\"\xF0\xAF\xBF\xBF\""));
    CHECK(json::accept("\"\xF0\xBF\xBF\xBF\""));
    CHECK(json::accept("\"\xF1\x8F\xBF\xBF\""));
    CHECK(json::accept("\"\xF1\x9F\xBF\xBF\""));
    CHECK(json::accept("\"\xF1\xAF\xBF\xBF\""));
    CHECK(json::accept("\"\xF1\xBF\xBF\xBF\""));
    CHECK(json::accept("\"\xF2\x8F\xBF\xBF\""));
    CHECK(json::accept("\"\xF2\x9F\xBF\xBF\""));
    CHECK(json::accept("\"\xF2\xAF\xBF\xBF\""));
}
  • cpp-test: [Unicode;unescaped unicode] (TSF/tests/unit-strings.cpp)

SECTION("unescaped unicode")
{
    for (uint32_t i = 0x0000; i<=0x10FFFF; i++)
    {
        std::string temp = uint_to_utf8(i);
        if ((i>=0xD800 && i<=0xDFFF)) { 
            // Unpaired utf-16 surrogates are illegal.
            // Observe that this verbatim not what RFC8259 §7 prescribes; 
            // it appears, however, to be in the spirit of RFC8259, cf. §8.2 
            // The other characters are illegal if unescaped.
            CHECK(!json::accept(temp));
            CHECK_THROWS_AS(parser_helper(temp),json::parse_error&);
            if (i<=0xDBFF){
                for (uint32_t j = 0xDC00; j<=0xDFFF; j++){
                    temp += uint_to_utf8(j);
                    CHECK(!json::accept(temp));
                    CHECK_THROWS_AS(parser_helper(temp),json::parse_error&);
                }
            } 
        } else if (i<0x0020||i==0x0022||i==0x005c){
            CHECK(!json::accept(temp));
            CHECK_THROWS_AS(parser_helper(temp),json::parse_error&);
        } else {
            // All other characters are valid according to RFC8259
            CHECK_NOTHROW(parser_helper(temp));
        }
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-12.6#

The service accepts well-formed UTF-8 data.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [Unicode;escaped unicode] (TSF/tests/unit-strings.cpp)

SECTION("escaped unicode")
{
    for (uint32_t i = 0x0000; i<=0xFFFF; i++)
    {
        std::ostringstream temp;
        std::ostringstream temp2;
        temp << "\"\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << i << "\"";
        temp2 << "\"\\u" << std::hex << std::nouppercase << std::setfill('0') << std::setw(4) << i << "\"";
        if (i>=0xD800 && i<=0xDFFF)
        {
            // Unpaired utf-16 surrogates are illegal.
            // Observe that this verbatim not what RFC8259 §7 prescribes; 
            // it appears, however, to be in the spirit of RFC8259, cf. §8.2 
            // Illegal characters are not parsed anyway.
            CHECK(!json::accept(temp.str()));
            CHECK(!json::accept(temp2.str()));
            CHECK_THROWS_AS(parser_helper(temp.str()),json::parse_error&);
            CHECK_THROWS_AS(parser_helper(temp2.str()),json::parse_error&);
        } else { 
            // all other characters of the basic multilingual plane are accepted.
            CHECK(json::accept(temp.str()));
            CHECK(json::accept(temp2.str()));
            CHECK(json::parse(temp.str())==json::parse(temp2.str()));
        }
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-13#

The service accepts JSON data consisting of combinations of the data types.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [compliance tests from json.org;expected passes] (tests/src/unit-testsuites.cpp)

SECTION("expected passes")
{
    for (const auto* filename :
            {
                TEST_DATA_DIRECTORY "/json_tests/pass1.json",
                TEST_DATA_DIRECTORY "/json_tests/pass2.json",
                TEST_DATA_DIRECTORY "/json_tests/pass3.json"
            })
    {
        CAPTURE(filename)
        std::ifstream f(filename);
        json j;
        CHECK_NOTHROW(f >> j);
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-14#

The service accepts a single complete UTF-8 byte order mark at the beginning of the input only.

Supported Requests:

Supporting Items:

References:

None

Fallacies:

None

Graph:

No Historic Data Found


NJF-14.1#

If the service accepts an input containing no BOM, then it accepts a single UTF-8 byte order mark followed by that input.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [accept;UTF-8;single BOM] (TSF/tests/unit-byte_order_mark.cpp)

SECTION("single BOM")
{
    // a single byte order mark is treated as an empty token, which is not a valid json token. 
    CHECK(!json::accept("\xEF\xBB\xBF"));
    CHECK(json::accept("\xEF\xBB\xBF\n\"foo\""));
    CHECK(json::accept("\xEF\xBB\xBF\"foo\""));
    CHECK(json::accept("\xEF\xBB\xBF 123"));
    CHECK(json::accept("\xEF\xBB\xBF[1,2,3]"));
    CHECK(json::accept("\xEF\xBB\xBF{\"foo\":1,\"bar\":2,\"test\":3}"));
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-14.2#

The service does not accept multiple UTF-8 byte order marks.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [accept;UTF-8;multiple BOM] (TSF/tests/unit-byte_order_mark.cpp)

SECTION("multiple BOM")
{
    CHECK(!json::accept("\xEF\xBB\xBF\xEF\xBB\xBF"));
    CHECK(!json::accept("\xEF\xBB\xBF\xEF\xBB\xBF\xEF\xBB\xBF"));
    CHECK(!json::accept("\xEF\xBB\xBF\xEF\xBB\xBF\xEF\xBB\xBF\xEF\xBB\xBF"));
    CHECK(!json::accept("\xEF\xBB\xBF\xEF\xBB"));
    CHECK(!json::accept("\xEF\xBB\xBF foo"));
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-14.3#

The service does not accept incomplete or perturbed UTF-8 byte order marks within the first three characters of the input.

Supported Requests:

Supporting Items:

None

References:

  • function: [parser::accept] (include/nlohmann/detail/input/parser.hpp)

    • Description: function, which implements the service to check for well-formed json

bool accept(const bool strict = true)
{
    json_sax_acceptor<BasicJsonType> sax_acceptor;
    return sax_parse(&sax_acceptor, strict);
}
  • function: [parser::sax_parse] (include/nlohmann/detail/input/parser.hpp)

    • Description: function, which is called by parser::accept

bool sax_parse(SAX* sax, const bool strict = true)
{
    (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
    const bool result = sax_parse_internal(sax);

    // strict mode: next byte must be EOF
    if (result && strict && (get_token() != token_type::end_of_input))
    {
        return sax->parse_error(m_lexer.get_position(),
                                m_lexer.get_token_string(),
                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
    }

    return result;
}
  • function: [parser::sax_parse_internal] (include/nlohmann/detail/input/parser.hpp)

    • Description: function, which is called by parser::sax_parse

bool sax_parse_internal(SAX* sax)
{
    // stack to remember the hierarchy of structured values we are parsing
    // true = array; false = object
    std::vector<bool> states;
    // value to avoid a goto (see comment where set to true)
    bool skip_to_state_evaluation = false;

    while (true)
    {
        if (!skip_to_state_evaluation)
        {
            // invariant: get_token() was called before each iteration
            switch (last_token)
            {
                case token_type::begin_object:
                {
                    if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
                    {
                        return false;
                    }

                    // closing } -> we are done
                    if (get_token() == token_type::end_object)
                    {
                        if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
                        {
                            return false;
                        }
                        break;
                    }

                    // parse key
                    if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
                    {
                        return sax->parse_error(m_lexer.get_position(),
                                                m_lexer.get_token_string(),
                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
                    }
                    if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
                    {
                        return false;
                    }

                    // parse separator (:)
                    if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
                    {
                        return sax->parse_error(m_lexer.get_position(),
                                                m_lexer.get_token_string(),
                                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
                    }

                    // remember we are now inside an object
                    states.push_back(false);

                    // parse values
                    get_token();
                    continue;
                }

                case token_type::begin_array:
                {
                    if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
                    {
                        return false;
                    }

                    // closing ] -> we are done
                    if (get_token() == token_type::end_array)
                    {
                        if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
                        {
                            return false;
                        }
                        break;
                    }

                    // remember we are now inside an array
                    states.push_back(true);

                    // parse values (no need to call get_token)
                    continue;
                }

                case token_type::value_float:
                {
                    const auto res = m_lexer.get_number_float();

                    if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
                    {
                        return sax->parse_error(m_lexer.get_position(),
                                                m_lexer.get_token_string(),
                                                out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
                    }

                    if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
                    {
                        return false;
                    }

                    break;
                }

                case token_type::literal_false:
                {
                    if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
                    {
                        return false;
                    }
                    break;
                }

                case token_type::literal_null:
                {
                    if (JSON_HEDLEY_UNLIKELY(!sax->null()))
                    {
                        return false;
                    }
                    break;
                }

                case token_type::literal_true:
                {
                    if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
                    {
                        return false;
                    }
                    break;
                }

                case token_type::value_integer:
                {
                    if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
                    {
                        return false;
                    }
                    break;
                }

                case token_type::value_string:
                {
                    if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
                    {
                        return false;
                    }
                    break;
                }

                case token_type::value_unsigned:
                {
                    if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
                    {
                        return false;
                    }
                    break;
                }

                case token_type::parse_error:
                {
                    // using "uninitialized" to avoid "expected" message
                    return sax->parse_error(m_lexer.get_position(),
                                            m_lexer.get_token_string(),
                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
                }
                case token_type::end_of_input:
                {
                    if (JSON_HEDLEY_UNLIKELY(m_lexer.get_position().chars_read_total == 1))
                    {
                        return sax->parse_error(m_lexer.get_position(),
                                                m_lexer.get_token_string(),
                                                parse_error::create(101, m_lexer.get_position(),
                                                        "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
                    }

                    return sax->parse_error(m_lexer.get_position(),
                                            m_lexer.get_token_string(),
                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
                }
                case token_type::uninitialized:
                case token_type::end_array:
                case token_type::end_object:
                case token_type::name_separator:
                case token_type::value_separator:
                case token_type::literal_or_value:
                default: // the last token was unexpected
                {
                    return sax->parse_error(m_lexer.get_position(),
                                            m_lexer.get_token_string(),
                                            parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
                }
            }
        }
        else
        {
            skip_to_state_evaluation = false;
        }

        // we reached this line after we successfully parsed a value
        if (states.empty())
        {
            // empty stack: we reached the end of the hierarchy: done
            return true;
        }

        if (states.back())  // array
        {
            // comma -> next value
            if (get_token() == token_type::value_separator)
            {
                // parse a new value
                get_token();
                continue;
            }

            // closing ]
            if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
            {
                if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
                {
                    return false;
                }

                // We are done with this array. Before we can parse a
                // new value, we need to evaluate the new state first.
                // By setting skip_to_state_evaluation to false, we
                // are effectively jumping to the beginning of this if.
                JSON_ASSERT(!states.empty());
                states.pop_back();
                skip_to_state_evaluation = true;
                continue;
            }

            return sax->parse_error(m_lexer.get_position(),
                                    m_lexer.get_token_string(),
                                    parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
        }

        // states.back() is false -> object

        // comma -> next value
        if (get_token() == token_type::value_separator)
        {
            // parse key
            if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
            {
                return sax->parse_error(m_lexer.get_position(),
                                        m_lexer.get_token_string(),
                                        parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
            }

            if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
            {
                return false;
            }

            // parse separator (:)
            if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
            {
                return sax->parse_error(m_lexer.get_position(),
                                        m_lexer.get_token_string(),
                                        parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
            }

            // parse values
            get_token();
            continue;
        }

        // closing }
        if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
        {
            if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
            {
                return false;
            }

            // We are done with this object. Before we can parse a
            // new value, we need to evaluate the new state first.
            // By setting skip_to_state_evaluation to false, we
            // are effectively jumping to the beginning of this if.
            JSON_ASSERT(!states.empty());
            states.pop_back();
            skip_to_state_evaluation = true;
            continue;
        }

        return sax->parse_error(m_lexer.get_position(),
                                m_lexer.get_token_string(),
                                parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
    }
}
  • function: [lexer::scan] (include/nlohmann/detail/input/lexer.hpp)

    • Description: function, which is called by parser::sax_parse_internal to read input data

token_type scan()
{
    // initially, skip the BOM
    if (position.chars_read_total == 0 && !skip_bom())
    {
        error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
        return token_type::parse_error;
    }

    // read next character and ignore whitespace
    skip_whitespace();

    // ignore comments
    while (ignore_comments && current == '/')
    {
        if (!scan_comment())
        {
            return token_type::parse_error;
        }

        // skip following whitespace
        skip_whitespace();
    }

    switch (current)
    {
        // structural characters
        case '[':
            return token_type::begin_array;
        case ']':
            return token_type::end_array;
        case '{':
            return token_type::begin_object;
        case '}':
            return token_type::end_object;
        case ':':
            return token_type::name_separator;
        case ',':
            return token_type::value_separator;

        // literals
        case 't':
        {
            std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
            return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
        }
        case 'f':
        {
            std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
            return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
        }
        case 'n':
        {
            std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
            return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
        }

        // string
        case '\"':
            return scan_string();

        // number
        case '-':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return scan_number();

        // end of input (the null byte is needed when parsing from
        // string literals)
        case '\0':
        case char_traits<char_type>::eof():
            return token_type::end_of_input;

        // error
        default:
            error_message = "invalid literal";
            return token_type::parse_error;
    }
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-14.4#

The service does not accept UTF-16 and UTF-32 byte order marks instead of the UTF-8 byte order mark.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [accept;UTF-8;Other byte-order marks;UTF-32] (TSF/tests/unit-byte_order_mark.cpp)

SECTION("UTF-32")
{
    const std::string utf32bom1("\x00\x00\xFE\xFF", 4);
    const std::string utf32bom2("\xFF\xFE\x00\x00", 4);
    CHECK(!json::accept(utf32bom1));
    CHECK(!json::accept(utf32bom2));
}

Fallacies:

None

Graph:

No Historic Data Found


NJF-14.5#

The service does not accept UTF-8 byte order mark outside of a string and outside of the first three characters of the input.

Supported Requests:

Supporting Items:

None

References:

  • cpp-test: [accept;UTF-8;unexpected BOM] (TSF/tests/unit-byte_order_mark.cpp)

SECTION("unexpected BOM")
{
    CHECK(!json::accept(" \xEF\xBB\xBF"));
    CHECK(!json::accept("\t\xEF\xBB\xBF"));
    CHECK(!json::accept("\n\xEF\xBB\xBF"));
    CHECK(!json::accept("\xEF\xBB\xBF"));
    CHECK(!json::accept("\u000d\xEF\xBB\xBF"));
    CHECK(!json::accept("1\xEF\xBB\xBF"));
    CHECK(!json::accept("\"foo\"\xEF\xBB\xBF"));
    CHECK(!json::accept("[42]\xEF\xBB\xBF"));
    CHECK(!json::accept("{\"foo\":\"bar\"}\xEF\xBB\xBF"));
}

Fallacies:

None

Graph:

No Historic Data Found