{"id":107632,"date":"2023-01-02T07:00:00","date_gmt":"2023-01-02T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=107632"},"modified":"2022-12-15T16:28:04","modified_gmt":"2022-12-16T00:28:04","slug":"20230102-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20230102-00\/?p=107632","title":{"rendered":"Opinionated notes on the Windows.Data.Json namespace"},"content":{"rendered":"<p>The Windows Runtime provides types in the <code>Windows.<wbr \/>Data.<wbr \/>Json<\/code> namespace for dealing with JSON. You can parse a JSON string into a JSON object model, and you can conversely build a JSON object model and then convert it back to a string.<\/p>\n<p>Here are some of my opinionated notes on these classes.<\/p>\n<p>In order to be language-independent, the objects in the Windows.Data.Json namespace are COM objects, rather than native objects in C++, C#, or whatever your language is. This means that calls to the methods go through vtable dispatch, which the compiler cannot optimize. This is a fundamental limitation of using a language-independent object model: You cannot take advantage of language-specific optimizations.<\/p>\n<p>There are a lot of interfaces, and calling a method on an interface different from the one you have in your hand requires you do perform a <code>QueryInterface<\/code> to switch to the interface that has the method.<\/p>\n<pre>\/\/ C++\/WinRT\r\nJsonObject jsonObject = ...;\r\njsonObject.Insert(key, value);\r\n<\/pre>\n<p>Insert is a method on <code>IMap&lt;String, IJsonValue&gt;<\/code>, so under the covers, there is an interface query.<\/p>\n<pre>IMap&lt;hstring, IJsonValue&gt; map;\r\njsonObject.QueryInterface(IID_PPV_ARGS(map.put()));\r\nmap.Insert(key, value);\r\n\/\/ map calls Release() on destruction\r\n<\/pre>\n<p>The above code could have avoided two COM calls (the <code>Query\u00adInterface<\/code> and the <code>Release<\/code>) by using the bespoke <code>Set\u00adNamed\u00adValue<\/code> method.<\/p>\n<pre>\/\/ C++\/WinRT\r\nJsonObject jsonObject = ...;\r\njsonObject.SetNamedValue(key, value);\r\n<\/pre>\n<p>The <code>SetNamedValue<\/code> method is a method on <code>IJsonObject<\/code>, so you can call it without having to change interfaces.<\/p>\n<p>The <code>JsonObject<\/code> is awkward to use in an exception-free manner. In order to read a value if it is present, most people write something like<\/p>\n<pre>if (jsonObject.HasKey(L\"name\")) {\r\n    auto value = jsonObject.GetNamedValue(L\"name\");\r\n    if (value.ValueType() == JsonValueType::String) {\r\n        auto name = value.GetString();\r\n    }\r\n}\r\n<\/pre>\n<p>This is a double-query, which is made even more expensive when you realize that <code>HasKey<\/code> is a method on <code>IMap<\/code>, so you also have an interface query\/release hiding in there.<\/p>\n<p>There&#8217;s a little-known overload of <code>GetNamedValue<\/code> that lets you specify what to return if the value isn&#8217;t found:<\/p>\n<pre>auto value = jsonObject.GetNamedValue(L\"name\", nullptr);\r\nif (value &amp;&amp; value.ValueType() == JsonValueType::String) {\r\n    auto name = value.GetString();\r\n}\r\n<\/pre>\n<p>Since a present named value never has a <code>nullptr<\/code> value, we can be confident that if <code>nullptr<\/code> is returned, then it means that the value was not present. (If the associated value is a JSON <code>null<\/code>, it is returned as a non-null object whose value type is <code>JsonValueType::<wbr \/>Null<\/code>.)<\/p>\n<p>There&#8217;s a corresponding little-known overload of <code>GetNamedString<\/code> that returns the string, or a fallback value if the string is not present.<\/p>\n<pre>auto name = jsonObject.GetNamedString(L\"name\", L\"untitled\");\r\n<\/pre>\n<p>Choosing a fallback value for a missing string is trickier because there is no out-of-band value that unmistakably indicates that the fallback was returned. (Recall that <a title=\"Raymonds complete guide to HSTRING semantics\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20160615-00\/?p=93675\"> a <code>nullptr<\/code> <code>HSTRING<\/code> represents the empty string<\/a>.) The <code>Get\u00adNamed\u00adBoolean<\/code> function suffers from the same problem. For <code>Get\u00adNamed\u00adValue<\/code> and <code>Get\u00adNamed\u00adArray<\/code>, you can use <code>nullptr<\/code>, and for <code>Get\u00adNamed\u00adNumber<\/code> you can use NaN or one of the Infinity values, since those are not legal in JSON.<\/p>\n<p>There&#8217;s still a hidden trap in the <code>Get\u00adNamed\u00ad...<\/code> functions with fallback: If the value is present but is not the type you expect, then instead of returning the fallback, you get an <code>E_<wbr \/>ILLEGAL_<wbr \/>METHOD_<wbr \/>CALL<\/code> error, which usually projects as an exception. This is a problem if you&#8217;re trying to be exception-free yet resilient to JSON that doesn&#8217;t match your schema. I think the best you can do is <code>Get\u00adNamed\u00adValue<\/code> and then check the <code>Value\u00adType<\/code> before converting.<\/p>\n<p>The JSON parsing and serialization methods are not configurable. Although there is a JSON specification, <a href=\"https:\/\/seriot.ch\/projects\/parsing_json.html\"> there is wide disagreement over what is legal JSON<\/a> when you get to the edges of the specification. I&#8217;ve put a conformance report at the end of this article.<\/p>\n<p>One thing that stands out from the conformance report is that the <code>TryParse<\/code> method can throw an exception if the JSON string is legal but not representable as a <code>JsonValue<\/code> object, or if an implementation limit is reached before the string can be fully validated. So even though you think you&#8217;re avoiding exceptions by using <code>JsonValue::<wbr \/>TryParse<\/code>, you aren&#8217;t actually exception-free.<\/p>\n<p>Anyway, back to lack of configurability: Since you cannot configure the input, you cannot specify which variant of JSON you want to accept. And since you cannot configure the output, you cannot ask for pretty-printing. This makes the <code>Windows.<wbr \/>Data.<wbr \/>Json<\/code> objects unsuitable for generating JSON configuration files which are intended to be human-edited.<\/p>\n<p>Note also that the <code>Windows.<wbr \/>Data.<wbr \/>Json<\/code> interconversion functions consume and produce UTF-16LE strings. Most of the time, the original JSON data in UTF-8 format, and the final output is also in UTF-8 format, so you have extra conversion steps on either side. Of course, this isn&#8217;t a problem if your I\/O functions already do that conversion for you. For example, if you ask <code>HttpClient<\/code> for the string content, it returns the string in UTF16-LE format, ready to be handed to <code>JsonValue::<wbr \/>TryParse<\/code>.<\/p>\n<p>With all of these caveats, it sure sounds like the <code>Windows.<wbr \/>Data.<wbr \/>Json<\/code> namespace is terrible. Why would you ever want to use it?<\/p>\n<p>Well, it&#8217;s already there.<\/p>\n<p>If you already require Windows 8 or higher, then these classes are already present, and you can consume them without having to add another dependency to your project. This is important if you are concerned about disk footprint or download size, or just want to minimize your dependencies. For example, I have a few internal tools in which the program itself is 60KB, but the dependencies to do the Web authentication are 300KB.<\/p>\n<p>Also, if parsing JSON is not a performance-critical operation in your program, you may figure that the inefficiencies of a language-independent library (compared to a native-language library) aren&#8217;t really a big deal. For example, if your program is parsing moderate-sized JSON received from a Web server, any time savings by switching to a highly-optimized JSON parser is almost certainly going to be overwhelmed by the network I\/O.\u00b9<\/p>\n<p><b>Bonus chatter<\/b>: The classes in the <code>Windows.<wbr \/>Data.<wbr \/>Json<\/code> namespace are provided by the Windows Runtime as a convenience. No other parts of the API surface require it.\u00b2 Any methods that accept JSON do so in the form of a string, so you are welcome to use whatever JSON library you like.<\/p>\n<p><b>Appendix<\/b>: Here&#8217;s the JSON conformance report, generated from <a href=\"https:\/\/github.com\/nst\/JSONTestSuite\"> Nicolas Seriot&#8217;s JSON test suite<\/a>.<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th>Test<\/th>\n<th>Result<\/th>\n<th>Notes<\/th>\n<\/tr>\n<tr>\n<td>i_number_double_huge_neg_exp<\/td>\n<td colspan=\"2\">Exception <code>WEB_E_INVALID_JSON_NUMBER<\/code><\/td>\n<\/tr>\n<tr>\n<td>i_number_huge_exp<\/td>\n<td colspan=\"2\">Exception <code>WEB_E_INVALID_JSON_NUMBER<\/code><\/td>\n<\/tr>\n<tr>\n<td>i_number_neg_int_huge_exp<\/td>\n<td colspan=\"2\">Exception <code>WEB_E_INVALID_JSON_NUMBER<\/code><\/td>\n<\/tr>\n<tr>\n<td>i_number_pos_double_huge_exp<\/td>\n<td colspan=\"2\">Exception <code>WEB_E_INVALID_JSON_NUMBER<\/code><\/td>\n<\/tr>\n<tr>\n<td>i_number_real_neg_overflow<\/td>\n<td colspan=\"2\">Exception <code>WEB_E_INVALID_JSON_NUMBER<\/code><\/td>\n<\/tr>\n<tr>\n<td>i_number_real_pos_overflow<\/td>\n<td colspan=\"2\">Exception <code>WEB_E_INVALID_JSON_NUMBER<\/code><\/td>\n<\/tr>\n<tr>\n<td>i_number_real_underflow<\/td>\n<td colspan=\"2\">Exception <code>WEB_E_INVALID_JSON_NUMBER<\/code><\/td>\n<\/tr>\n<tr>\n<td>i_number_too_big_neg_int<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_number_too_big_pos_int<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_number_very_big_negative_int<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_object_key_lone_2nd_surrogate<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_1st_surrogate_but_2nd_missing<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_1st_valid_surrogate_2nd_invalid<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_incomplete_surrogates_escape_valid<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_incomplete_surrogate_and_escape_valid<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_incomplete_surrogate_pair<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_invalid_lonely_surrogate<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_invalid_surrogate<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_invalid_utf-8<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_inverted_surrogates_U+1D11E<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_iso_latin_1<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_lone_second_surrogate<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_lone_utf8_continuation_byte<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_not_in_unicode_range<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_overlong_sequence_2_bytes<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_overlong_sequence_6_bytes<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_overlong_sequence_6_bytes_null<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_truncated-utf-8<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_UTF-16LE_with_BOM<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_UTF-8_invalid_sequence<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_utf16BE_no_BOM<\/td>\n<td>Reject<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_utf16LE_no_BOM<\/td>\n<td>Reject<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_string_UTF8_surrogate_U+D800<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_structure_500_nested_arrays<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>i_structure_UTF-8_BOM_empty_object<\/td>\n<td>Accept<\/td>\n<td>Allowed<\/td>\n<\/tr>\n<tr>\n<td>n_array_1_true_without_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_a_invalid_utf8<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_colon_instead_of_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_comma_after_close<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_comma_and_number<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_double_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_double_extra_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_extra_close<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_extra_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_incomplete<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_incomplete_invalid_value<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_inner_array_no_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_invalid_utf8<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_items_separated_by_semicolon<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_just_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_just_minus<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_missing_value<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_newlines_unclosed<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_number_and_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_number_and_several_commas<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_spaces_vertical_tab_formfeed<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_star_inside<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_unclosed<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_unclosed_trailing_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_unclosed_with_new_lines<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_array_unclosed_with_object_inside<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_incomplete_false<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_incomplete_null<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_incomplete_true<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_multidigit_number_then_00<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_++<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_+1<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_+Inf<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_-01<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_-1.0.<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_-2.<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_-NaN<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_.-1<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_.2e-3<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_0.1.2<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_0.3e+<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_0.3e<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_0.e1<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_0e+<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_0e<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_0_capital_E+<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_0_capital_E<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_1.0e+<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_1.0e-<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_1.0e<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_1eE2<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_1_000<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_2.e+3<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_2.e-3<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_2.e3<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_9.e+<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_expression<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_hex_1_digit<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_hex_2_digits<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_Inf<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_infinity<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_invalid+-<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_invalid-negative-real<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_invalid-utf-8-in-bigger-int<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_invalid-utf-8-in-exponent<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_invalid-utf-8-in-int<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_minus_infinity<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_minus_sign_with_trailing_garbage<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_minus_space_1<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_NaN<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_neg_int_starting_with_zero<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_neg_real_without_int_part<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_neg_with_garbage_at_end<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_real_garbage_after_e<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_real_without_fractional_part<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_real_with_invalid_utf8_after_e<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_starting_with_dot<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_U+FF11_fullwidth_digit_one<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_with_alpha<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_with_alpha_char<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_number_with_leading_zero<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_bad_value<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_bracket_key<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_comma_instead_of_colon<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_double_colon<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_emoji<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_garbage_at_end<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_key_with_single_quotes<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_lone_continuation_byte_in_<br \/>\nkey_and_trailing_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_missing_colon<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_missing_key<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_missing_semicolon<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_missing_value<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_no-colon<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_non_string_key<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_non_string_key_<br \/>\nbut_huge_number_instead<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_repeated_null_null<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_several_trailing_commas<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_single_quote<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_trailing_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_trailing_comment<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_trailing_comment_open<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_trailing_comment_slash_open<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_trailing_comment_slash_open_incomplete<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_two_commas_in_a_row<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_unquoted_key<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_unterminated-value<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_with_single_string<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_object_with_trailing_garbage<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_single_space<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_1_surrogate_then_escape<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_1_surrogate_then_escape_u<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_1_surrogate_then_escape_u1<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_1_surrogate_then_escape_u1x<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_accentuated_char_no_quotes<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_backslash_00<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_escaped_backslash_bad<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_escaped_ctrl_char_tab<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_escaped_emoji<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_escape_x<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_incomplete_escape<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_incomplete_escaped_character<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_incomplete_surrogate<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_incomplete_surrogate_escape_invalid<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_invalid-utf-8-in-escape<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_invalid_backslash_esc<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_invalid_unicode_escape<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_invalid_utf8_after_escape<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_leading_uescaped_thinspace<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_no_quotes_with_bad_escape<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_single_doublequote<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_single_quote<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_single_string_no_double_quotes<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_start_escape_unclosed<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_unescaped_ctrl_char<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_unescaped_newline<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_unescaped_tab<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_unicode_CapitalU<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_string_with_trailing_garbage<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_100000_opening_arrays<\/td>\n<td colspan=\"2\">Exception <code>ERROR_IMPLEMENTATION_LIMIT<\/code><\/td>\n<\/tr>\n<tr>\n<td>n_structure_angle_bracket_.<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_angle_bracket_null<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_array_trailing_garbage<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_array_with_extra_array_close<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_array_with_unclosed_string<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_ascii-unicode-identifier<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_capitalized_True<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_close_unopened_array<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_comma_instead_of_closing_brace<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_double_array<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_end_array<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_incomplete_UTF8_BOM<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_lone-invalid-utf-8<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_lone-open-bracket<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_no_data<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_null-byte-outside-string<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_number_with_trailing_garbage<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_object_followed_by_closing_object<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_object_unclosed_no_value<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_object_with_comment<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_object_with_trailing_garbage<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_array_apostrophe<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_array_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_array_object<\/td>\n<td colspan=\"2\">Exception <code>ERROR_IMPLEMENTATION_LIMIT<\/code><\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_array_open_object<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_array_open_string<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_array_string<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_object<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_object_close_array<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_object_comma<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_object_open_array<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_object_open_string<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_object_string_with_apostrophes<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_open_open<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_single_eacute<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_single_star<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_trailing_#<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_U+2060_word_joined<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_uescaped_LF_before_string<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_unclosed_array<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_unclosed_array_partial_null<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_unclosed_array_unfinished_false<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_unclosed_array_unfinished_true<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_unclosed_object<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_unicode-identifier<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_UTF8_BOM_no_data<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_whitespace_formfeed<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>n_structure_whitespace_U+2060_word_joiner<\/td>\n<td>Reject<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_arraysWithSpaces<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_empty-string<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_empty<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_ending_with_newline<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_false<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_heterogeneous<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_null<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_with_1_and_newline<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_with_leading_space<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_with_several_null<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_array_with_trailing_space<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_0e+1<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_0e1<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_after_space<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_double_close_to_zero<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_int_with_exp<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_minus_zero<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_negative_int<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_negative_one<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_negative_zero<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_real_capital_e<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_real_capital_e_neg_exp<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_real_capital_e_pos_exp<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_real_exponent<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_real_fraction_exponent<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_real_neg_exp<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_real_pos_exponent<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_simple_int<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_number_simple_real<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_basic<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_duplicated_key<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_duplicated_key_and_value<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_empty<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_empty_key<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_escaped_null_in_key<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_extreme_numbers<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_long_strings<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_simple<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_string_unicode<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_object_with_newlines<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_1_2_3_bytes_UTF-8_sequences<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_accepted_surrogate_pair<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_accepted_surrogate_pairs<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_allowed_escapes<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_backslash_and_u_escaped_zero<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_backslash_doublequotes<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_comments<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_double_escape_a<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_double_escape_n<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_escaped_control_character<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_escaped_noncharacter<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_in_array<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_in_array_with_leading_space<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_last_surrogates_1_and_2<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_nbsp_uescaped<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_nonCharacterInUTF-8_U+10FFFF<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_nonCharacterInUTF-8_U+FFFF<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_null_escape<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_one-byte-utf-8<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_pi<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_reservedCharacterInUTF-8_U+1BFFF<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_simple_ascii<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_space<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_surrogates_U+1D11E_<br \/>\nMUSICAL_SYMBOL_G_CLEF<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_three-byte-utf-8<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_two-byte-utf-8<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_u+2028_line_sep<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_u+2029_par_sep<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_uEscape<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_uescaped_newline<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unescaped_char_delete<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unicode<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unicodeEscapedBackslash<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unicode_2<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unicode_escaped_double_quote<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unicode_U+10FFFE_nonchar<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unicode_U+1FFFE_nonchar<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unicode_U+200B_ZERO_WIDTH_SPACE<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unicode_U+2064_invisible_plus<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unicode_U+FDD0_nonchar<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_unicode_U+FFFE_nonchar<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_utf8<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_string_with_del_character<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_structure_lonely_false<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_structure_lonely_int<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_structure_lonely_negative_real<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_structure_lonely_null<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_structure_lonely_string<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_structure_lonely_true<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_structure_string_empty<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_structure_trailing_newline<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_structure_true_in_array<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>y_structure_whitespace_array<\/td>\n<td>Accept<\/td>\n<td>OK<\/td>\n<\/tr>\n<tr>\n<td>number_-9223372036854775808<\/td>\n<td colspan=\"2\"><code>[-9.2233720368547758E+18]<\/code><\/td>\n<\/tr>\n<tr>\n<td>number_-9223372036854775809<\/td>\n<td colspan=\"2\"><code>[-9.2233720368547758E+18]<\/code><\/td>\n<\/tr>\n<tr>\n<td>number_1.0<\/td>\n<td colspan=\"2\"><code>[1]<\/code><\/td>\n<\/tr>\n<tr>\n<td>number_1.000000000000000005<\/td>\n<td colspan=\"2\"><code>[1]<\/code><\/td>\n<\/tr>\n<tr>\n<td>number_1000000000000000<\/td>\n<td colspan=\"2\"><code>[1E+15]<\/code><\/td>\n<\/tr>\n<tr>\n<td>number_10000000000000000999<\/td>\n<td colspan=\"2\"><code>[1E+19]<\/code><\/td>\n<\/tr>\n<tr>\n<td>number_1e-999<\/td>\n<td colspan=\"2\">Exception <code>WEB_E_INVALID_JSON_NUMBER<\/code><\/td>\n<\/tr>\n<tr>\n<td>number_1e6<\/td>\n<td colspan=\"2\"><code>[1000000]<\/code><\/td>\n<\/tr>\n<tr>\n<td>number_9223372036854775807<\/td>\n<td colspan=\"2\"><code>[9.2233720368547758E+18]<\/code><\/td>\n<\/tr>\n<tr>\n<td>number_9223372036854775808<\/td>\n<td colspan=\"2\">[9.2233720368547758E+18]<\/td>\n<\/tr>\n<tr>\n<td>object_key_nfc_nfd<\/td>\n<td colspan=\"2\"><code>{\"<u>C3<\/u><u>A9<\/u>\":\"NFC\",\"<u>65<\/u><u>CC<\/u><u>81<\/u>\":\"NFD\"}<\/code><\/td>\n<\/tr>\n<tr>\n<td>object_key_nfd_nfc<\/td>\n<td colspan=\"2\"><code>{\"<u>65<\/u><u>CC<\/u><u>81<\/u>\":\"NFD\",\"<u>C3<\/u><u>A9<\/u>\":\"NFC\"}<\/code><\/td>\n<\/tr>\n<tr>\n<td>object_same_key_different_values<\/td>\n<td colspan=\"2\"><code>{\"a\":2}<\/code><\/td>\n<\/tr>\n<tr>\n<td>object_same_key_same_value<\/td>\n<td colspan=\"2\"><code>{\"a\":1}<\/code><\/td>\n<\/tr>\n<tr>\n<td>object_same_key_unclear_values<\/td>\n<td colspan=\"2\"><code>{\"a\":-0}<\/code><\/td>\n<\/tr>\n<tr>\n<td>string_1_escaped_invalid_codepoint<\/td>\n<td colspan=\"2\"><code>[\"<u>EF<\/u><u>BF<\/u><u>BD<\/u>\"]<\/code><\/td>\n<\/tr>\n<tr>\n<td>string_1_invalid_codepoint<\/td>\n<td colspan=\"2\">N\/A<\/td>\n<\/tr>\n<tr>\n<td>string_2_escaped_invalid_codepoints<\/td>\n<td colspan=\"2\"><code>[\"<u>EF<\/u><u>BF<\/u><u>BD<\/u><u>EF<\/u><u>BF<\/u><u>BD<\/u>\"]<\/code><\/td>\n<\/tr>\n<tr>\n<td>string_2_invalid_codepoints<\/td>\n<td colspan=\"2\">N\/A<\/td>\n<\/tr>\n<tr>\n<td>string_3_escaped_invalid_codepoints<\/td>\n<td colspan=\"2\"><code>[\"<u>EF<\/u><u>BF<\/u><u>BD<\/u><u>EF<\/u><u>BF<\/u><u>BD<\/u><u>EF<\/u><u>BF<\/u><u>BD<\/u>\"]<\/code><\/td>\n<\/tr>\n<tr>\n<td>string_3_invalid_codepoints<\/td>\n<td colspan=\"2\">N\/A<\/td>\n<\/tr>\n<tr>\n<td>string_with_escaped_NULL<\/td>\n<td colspan=\"2\"><code>[\"A\\u0000B\"]<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>For all of the &#8220;invalid codepoint&#8221; tests, the <u>EF<\/u><u>BF<\/u><u>BD<\/u> sequence is an encoded \ufffd U+FFFD REPLACEMENT CHARACTER.<\/p>\n<p>The &#8220;raw invalid codepoint&#8221; tests are marked N\/A because the failure is in the conversion from UTF-8 to UTF-16LE, which is something the caller does before calling <code>JsonValue::<wbr \/>TryParse<\/code>.<\/p>\n<p>\u00b9 Though <a title=\"How I cut GTA Online loading times by 70%\" href=\"https:\/\/nee.lv\/2021\/02\/28\/How-I-cut-GTA-Online-loading-times-by-70\/\"> not always<\/a>.<\/p>\n<p>\u00b2 The <a href=\"https:\/\/docs.microsoft.com\/en-us\/uwp\/api\/Windows.System.Diagnostics.DiagnosticInvoker.RunDiagnosticActionAsync?view=winrt-22621\"> <code>Windows.<wbr \/>System.<wbr \/>Diagnostics.<wbr \/>Diagnostic\u00adInvoker.<wbr \/>Run\u00adDiagnostic\u00adAction\u00adAsync<\/code><\/a> method does require that you use a <code>Windows.<wbr \/>Data.<wbr \/>Json.<wbr \/>JsonObject<\/code>, but this was a mistake, which was corrected by the addition of the <a href=\"https:\/\/docs.microsoft.com\/en-us\/uwp\/api\/Windows.System.Diagnostics.DiagnosticInvoker.RunDiagnosticActionFromStringAsync?view=winrt-22621\"> <code>Windows.<wbr \/>System.<wbr \/>Diagnostics.<wbr \/>Diagnostic\u00adInvoker.<wbr \/>Run\u00adDiagnostic\u00adAction\u00adFrom\u00adString\u00adAsync<\/code><\/a> method, which accepts a plain string. You can generate that string using whatever JSON library you choose.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s available if you need it, but there are some tricks and pitfalls, and you may very well have better options.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-107632","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It&#8217;s available if you need it, but there are some tricks and pitfalls, and you may very well have better options.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107632","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=107632"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107632\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=107632"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=107632"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=107632"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}