diff --git a/resources/json/README.md b/resources/json/README.md new file mode 100644 index 0000000..533092f --- /dev/null +++ b/resources/json/README.md @@ -0,0 +1,14 @@ +# Test JSON + +This directory contains test JSON files from https://github.com/nst/JSONTestSuite as of commit 984defc. + +It only has the positive and questionable JSON inputs, as our JSON parser is extremely forgiving, by design. + +## Filtered tests + +Some of the questionable tests have been removed: + +- `i_structure_UTF-8_BOM_empty_object.json` removed because we don't handle BOMs. +- `i_string_utf16LE_no_BOM.json` removed because we don't speak UTF16. +- `i_string_utf16BE_no_BOM.json` removed because we don't speak UTF16. +- `i_string_UTF-16LE_with_BOM.json` removed because we don't speak UTF16. diff --git a/resources/json/i_number_double_huge_neg_exp.json b/resources/json/i_number_double_huge_neg_exp.json new file mode 100644 index 0000000..ae4c7b7 --- /dev/null +++ b/resources/json/i_number_double_huge_neg_exp.json @@ -0,0 +1 @@ +[123.456e-789] \ No newline at end of file diff --git a/resources/json/i_number_huge_exp.json b/resources/json/i_number_huge_exp.json new file mode 100644 index 0000000..9b5efa2 --- /dev/null +++ b/resources/json/i_number_huge_exp.json @@ -0,0 +1 @@ +[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006] \ No newline at end of file diff --git a/resources/json/i_number_neg_int_huge_exp.json b/resources/json/i_number_neg_int_huge_exp.json new file mode 100755 index 0000000..3abd58a --- /dev/null +++ b/resources/json/i_number_neg_int_huge_exp.json @@ -0,0 +1 @@ +[-1e+9999] \ No newline at end of file diff --git a/resources/json/i_number_pos_double_huge_exp.json b/resources/json/i_number_pos_double_huge_exp.json new file mode 100755 index 0000000..e10a7eb --- /dev/null +++ b/resources/json/i_number_pos_double_huge_exp.json @@ -0,0 +1 @@ +[1.5e+9999] \ No newline at end of file diff --git a/resources/json/i_number_real_neg_overflow.json b/resources/json/i_number_real_neg_overflow.json new file mode 100644 index 0000000..3d628a9 --- /dev/null +++ b/resources/json/i_number_real_neg_overflow.json @@ -0,0 +1 @@ +[-123123e100000] \ No newline at end of file diff --git a/resources/json/i_number_real_pos_overflow.json b/resources/json/i_number_real_pos_overflow.json new file mode 100644 index 0000000..54d7d3d --- /dev/null +++ b/resources/json/i_number_real_pos_overflow.json @@ -0,0 +1 @@ +[123123e100000] \ No newline at end of file diff --git a/resources/json/i_number_real_underflow.json b/resources/json/i_number_real_underflow.json new file mode 100644 index 0000000..c5236eb --- /dev/null +++ b/resources/json/i_number_real_underflow.json @@ -0,0 +1 @@ +[123e-10000000] \ No newline at end of file diff --git a/resources/json/i_number_too_big_neg_int.json b/resources/json/i_number_too_big_neg_int.json new file mode 100644 index 0000000..dfa3846 --- /dev/null +++ b/resources/json/i_number_too_big_neg_int.json @@ -0,0 +1 @@ +[-123123123123123123123123123123] \ No newline at end of file diff --git a/resources/json/i_number_too_big_pos_int.json b/resources/json/i_number_too_big_pos_int.json new file mode 100644 index 0000000..338a8c3 --- /dev/null +++ b/resources/json/i_number_too_big_pos_int.json @@ -0,0 +1 @@ +[100000000000000000000] \ No newline at end of file diff --git a/resources/json/i_number_very_big_negative_int.json b/resources/json/i_number_very_big_negative_int.json new file mode 100755 index 0000000..e2d9738 --- /dev/null +++ b/resources/json/i_number_very_big_negative_int.json @@ -0,0 +1 @@ +[-237462374673276894279832749832423479823246327846] \ No newline at end of file diff --git a/resources/json/i_object_key_lone_2nd_surrogate.json b/resources/json/i_object_key_lone_2nd_surrogate.json new file mode 100644 index 0000000..5be7eba --- /dev/null +++ b/resources/json/i_object_key_lone_2nd_surrogate.json @@ -0,0 +1 @@ +{"\uDFAA":0} \ No newline at end of file diff --git a/resources/json/i_string_1st_surrogate_but_2nd_missing.json b/resources/json/i_string_1st_surrogate_but_2nd_missing.json new file mode 100644 index 0000000..3b9e37c --- /dev/null +++ b/resources/json/i_string_1st_surrogate_but_2nd_missing.json @@ -0,0 +1 @@ +["\uDADA"] \ No newline at end of file diff --git a/resources/json/i_string_1st_valid_surrogate_2nd_invalid.json b/resources/json/i_string_1st_valid_surrogate_2nd_invalid.json new file mode 100644 index 0000000..4875928 --- /dev/null +++ b/resources/json/i_string_1st_valid_surrogate_2nd_invalid.json @@ -0,0 +1 @@ +["\uD888\u1234"] \ No newline at end of file diff --git a/resources/json/i_string_UTF-8_invalid_sequence.json b/resources/json/i_string_UTF-8_invalid_sequence.json new file mode 100755 index 0000000..e2a968a --- /dev/null +++ b/resources/json/i_string_UTF-8_invalid_sequence.json @@ -0,0 +1 @@ +["日ш"] \ No newline at end of file diff --git a/resources/json/i_string_UTF8_surrogate_U+D800.json b/resources/json/i_string_UTF8_surrogate_U+D800.json new file mode 100644 index 0000000..916bff9 --- /dev/null +++ b/resources/json/i_string_UTF8_surrogate_U+D800.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/i_string_incomplete_surrogate_and_escape_valid.json b/resources/json/i_string_incomplete_surrogate_and_escape_valid.json new file mode 100755 index 0000000..3cb11d2 --- /dev/null +++ b/resources/json/i_string_incomplete_surrogate_and_escape_valid.json @@ -0,0 +1 @@ +["\uD800\n"] \ No newline at end of file diff --git a/resources/json/i_string_incomplete_surrogate_pair.json b/resources/json/i_string_incomplete_surrogate_pair.json new file mode 100755 index 0000000..38ec23b --- /dev/null +++ b/resources/json/i_string_incomplete_surrogate_pair.json @@ -0,0 +1 @@ +["\uDd1ea"] \ No newline at end of file diff --git a/resources/json/i_string_incomplete_surrogates_escape_valid.json b/resources/json/i_string_incomplete_surrogates_escape_valid.json new file mode 100755 index 0000000..c9cd6f6 --- /dev/null +++ b/resources/json/i_string_incomplete_surrogates_escape_valid.json @@ -0,0 +1 @@ +["\uD800\uD800\n"] \ No newline at end of file diff --git a/resources/json/i_string_invalid_lonely_surrogate.json b/resources/json/i_string_invalid_lonely_surrogate.json new file mode 100755 index 0000000..3abbd8d --- /dev/null +++ b/resources/json/i_string_invalid_lonely_surrogate.json @@ -0,0 +1 @@ +["\ud800"] \ No newline at end of file diff --git a/resources/json/i_string_invalid_surrogate.json b/resources/json/i_string_invalid_surrogate.json new file mode 100755 index 0000000..ffddc04 --- /dev/null +++ b/resources/json/i_string_invalid_surrogate.json @@ -0,0 +1 @@ +["\ud800abc"] \ No newline at end of file diff --git a/resources/json/i_string_invalid_utf-8.json b/resources/json/i_string_invalid_utf-8.json new file mode 100644 index 0000000..8e45a7e --- /dev/null +++ b/resources/json/i_string_invalid_utf-8.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/i_string_inverted_surrogates_U+1D11E.json b/resources/json/i_string_inverted_surrogates_U+1D11E.json new file mode 100755 index 0000000..0d5456c --- /dev/null +++ b/resources/json/i_string_inverted_surrogates_U+1D11E.json @@ -0,0 +1 @@ +["\uDd1e\uD834"] \ No newline at end of file diff --git a/resources/json/i_string_iso_latin_1.json b/resources/json/i_string_iso_latin_1.json new file mode 100644 index 0000000..9389c98 --- /dev/null +++ b/resources/json/i_string_iso_latin_1.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/i_string_lone_second_surrogate.json b/resources/json/i_string_lone_second_surrogate.json new file mode 100644 index 0000000..1dbd397 --- /dev/null +++ b/resources/json/i_string_lone_second_surrogate.json @@ -0,0 +1 @@ +["\uDFAA"] \ No newline at end of file diff --git a/resources/json/i_string_lone_utf8_continuation_byte.json b/resources/json/i_string_lone_utf8_continuation_byte.json new file mode 100644 index 0000000..729337c --- /dev/null +++ b/resources/json/i_string_lone_utf8_continuation_byte.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/i_string_not_in_unicode_range.json b/resources/json/i_string_not_in_unicode_range.json new file mode 100644 index 0000000..df90a29 --- /dev/null +++ b/resources/json/i_string_not_in_unicode_range.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/i_string_overlong_sequence_2_bytes.json b/resources/json/i_string_overlong_sequence_2_bytes.json new file mode 100644 index 0000000..c8cee5e --- /dev/null +++ b/resources/json/i_string_overlong_sequence_2_bytes.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/i_string_overlong_sequence_6_bytes.json b/resources/json/i_string_overlong_sequence_6_bytes.json new file mode 100755 index 0000000..9a91da7 --- /dev/null +++ b/resources/json/i_string_overlong_sequence_6_bytes.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/i_string_overlong_sequence_6_bytes_null.json b/resources/json/i_string_overlong_sequence_6_bytes_null.json new file mode 100755 index 0000000..d24fffd --- /dev/null +++ b/resources/json/i_string_overlong_sequence_6_bytes_null.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/i_string_truncated-utf-8.json b/resources/json/i_string_truncated-utf-8.json new file mode 100644 index 0000000..63c7777 --- /dev/null +++ b/resources/json/i_string_truncated-utf-8.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/i_structure_500_nested_arrays.json b/resources/json/i_structure_500_nested_arrays.json new file mode 100644 index 0000000..7118405 --- /dev/null +++ b/resources/json/i_structure_500_nested_arrays.json @@ -0,0 +1 @@ +[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/resources/json/y_array_arraysWithSpaces.json b/resources/json/y_array_arraysWithSpaces.json new file mode 100755 index 0000000..5822907 --- /dev/null +++ b/resources/json/y_array_arraysWithSpaces.json @@ -0,0 +1 @@ +[[] ] \ No newline at end of file diff --git a/resources/json/y_array_empty-string.json b/resources/json/y_array_empty-string.json new file mode 100644 index 0000000..93b6be2 --- /dev/null +++ b/resources/json/y_array_empty-string.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/y_array_empty.json b/resources/json/y_array_empty.json new file mode 100755 index 0000000..0637a08 --- /dev/null +++ b/resources/json/y_array_empty.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/resources/json/y_array_ending_with_newline.json b/resources/json/y_array_ending_with_newline.json new file mode 100755 index 0000000..eac5f7b --- /dev/null +++ b/resources/json/y_array_ending_with_newline.json @@ -0,0 +1 @@ +["a"] \ No newline at end of file diff --git a/resources/json/y_array_false.json b/resources/json/y_array_false.json new file mode 100644 index 0000000..67b2f07 --- /dev/null +++ b/resources/json/y_array_false.json @@ -0,0 +1 @@ +[false] \ No newline at end of file diff --git a/resources/json/y_array_heterogeneous.json b/resources/json/y_array_heterogeneous.json new file mode 100755 index 0000000..d3c1e26 --- /dev/null +++ b/resources/json/y_array_heterogeneous.json @@ -0,0 +1 @@ +[null, 1, "1", {}] \ No newline at end of file diff --git a/resources/json/y_array_null.json b/resources/json/y_array_null.json new file mode 100644 index 0000000..500db4a --- /dev/null +++ b/resources/json/y_array_null.json @@ -0,0 +1 @@ +[null] \ No newline at end of file diff --git a/resources/json/y_array_with_1_and_newline.json b/resources/json/y_array_with_1_and_newline.json new file mode 100644 index 0000000..9948255 --- /dev/null +++ b/resources/json/y_array_with_1_and_newline.json @@ -0,0 +1,2 @@ +[1 +] \ No newline at end of file diff --git a/resources/json/y_array_with_leading_space.json b/resources/json/y_array_with_leading_space.json new file mode 100755 index 0000000..18bfe64 --- /dev/null +++ b/resources/json/y_array_with_leading_space.json @@ -0,0 +1 @@ + [1] \ No newline at end of file diff --git a/resources/json/y_array_with_several_null.json b/resources/json/y_array_with_several_null.json new file mode 100755 index 0000000..99f6c5d --- /dev/null +++ b/resources/json/y_array_with_several_null.json @@ -0,0 +1 @@ +[1,null,null,null,2] \ No newline at end of file diff --git a/resources/json/y_array_with_trailing_space.json b/resources/json/y_array_with_trailing_space.json new file mode 100755 index 0000000..de9e7a9 --- /dev/null +++ b/resources/json/y_array_with_trailing_space.json @@ -0,0 +1 @@ +[2] \ No newline at end of file diff --git a/resources/json/y_number.json b/resources/json/y_number.json new file mode 100644 index 0000000..e5f5cc3 --- /dev/null +++ b/resources/json/y_number.json @@ -0,0 +1 @@ +[123e65] \ No newline at end of file diff --git a/resources/json/y_number_0e+1.json b/resources/json/y_number_0e+1.json new file mode 100755 index 0000000..d1d3967 --- /dev/null +++ b/resources/json/y_number_0e+1.json @@ -0,0 +1 @@ +[0e+1] \ No newline at end of file diff --git a/resources/json/y_number_0e1.json b/resources/json/y_number_0e1.json new file mode 100755 index 0000000..3283a79 --- /dev/null +++ b/resources/json/y_number_0e1.json @@ -0,0 +1 @@ +[0e1] \ No newline at end of file diff --git a/resources/json/y_number_after_space.json b/resources/json/y_number_after_space.json new file mode 100644 index 0000000..623570d --- /dev/null +++ b/resources/json/y_number_after_space.json @@ -0,0 +1 @@ +[ 4] \ No newline at end of file diff --git a/resources/json/y_number_double_close_to_zero.json b/resources/json/y_number_double_close_to_zero.json new file mode 100755 index 0000000..96555ff --- /dev/null +++ b/resources/json/y_number_double_close_to_zero.json @@ -0,0 +1 @@ +[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001] diff --git a/resources/json/y_number_int_with_exp.json b/resources/json/y_number_int_with_exp.json new file mode 100755 index 0000000..a4ca9e7 --- /dev/null +++ b/resources/json/y_number_int_with_exp.json @@ -0,0 +1 @@ +[20e1] \ No newline at end of file diff --git a/resources/json/y_number_minus_zero.json b/resources/json/y_number_minus_zero.json new file mode 100755 index 0000000..37af131 --- /dev/null +++ b/resources/json/y_number_minus_zero.json @@ -0,0 +1 @@ +[-0] \ No newline at end of file diff --git a/resources/json/y_number_negative_int.json b/resources/json/y_number_negative_int.json new file mode 100644 index 0000000..8e30f8b --- /dev/null +++ b/resources/json/y_number_negative_int.json @@ -0,0 +1 @@ +[-123] \ No newline at end of file diff --git a/resources/json/y_number_negative_one.json b/resources/json/y_number_negative_one.json new file mode 100644 index 0000000..99d21a2 --- /dev/null +++ b/resources/json/y_number_negative_one.json @@ -0,0 +1 @@ +[-1] \ No newline at end of file diff --git a/resources/json/y_number_negative_zero.json b/resources/json/y_number_negative_zero.json new file mode 100644 index 0000000..37af131 --- /dev/null +++ b/resources/json/y_number_negative_zero.json @@ -0,0 +1 @@ +[-0] \ No newline at end of file diff --git a/resources/json/y_number_real_capital_e.json b/resources/json/y_number_real_capital_e.json new file mode 100644 index 0000000..6edbdfc --- /dev/null +++ b/resources/json/y_number_real_capital_e.json @@ -0,0 +1 @@ +[1E22] \ No newline at end of file diff --git a/resources/json/y_number_real_capital_e_neg_exp.json b/resources/json/y_number_real_capital_e_neg_exp.json new file mode 100644 index 0000000..0a01bd3 --- /dev/null +++ b/resources/json/y_number_real_capital_e_neg_exp.json @@ -0,0 +1 @@ +[1E-2] \ No newline at end of file diff --git a/resources/json/y_number_real_capital_e_pos_exp.json b/resources/json/y_number_real_capital_e_pos_exp.json new file mode 100644 index 0000000..5a8fc09 --- /dev/null +++ b/resources/json/y_number_real_capital_e_pos_exp.json @@ -0,0 +1 @@ +[1E+2] \ No newline at end of file diff --git a/resources/json/y_number_real_exponent.json b/resources/json/y_number_real_exponent.json new file mode 100644 index 0000000..da2522d --- /dev/null +++ b/resources/json/y_number_real_exponent.json @@ -0,0 +1 @@ +[123e45] \ No newline at end of file diff --git a/resources/json/y_number_real_fraction_exponent.json b/resources/json/y_number_real_fraction_exponent.json new file mode 100644 index 0000000..3944a7a --- /dev/null +++ b/resources/json/y_number_real_fraction_exponent.json @@ -0,0 +1 @@ +[123.456e78] \ No newline at end of file diff --git a/resources/json/y_number_real_neg_exp.json b/resources/json/y_number_real_neg_exp.json new file mode 100644 index 0000000..ca40d3c --- /dev/null +++ b/resources/json/y_number_real_neg_exp.json @@ -0,0 +1 @@ +[1e-2] \ No newline at end of file diff --git a/resources/json/y_number_real_pos_exponent.json b/resources/json/y_number_real_pos_exponent.json new file mode 100644 index 0000000..343601d --- /dev/null +++ b/resources/json/y_number_real_pos_exponent.json @@ -0,0 +1 @@ +[1e+2] \ No newline at end of file diff --git a/resources/json/y_number_simple_int.json b/resources/json/y_number_simple_int.json new file mode 100644 index 0000000..e47f69a --- /dev/null +++ b/resources/json/y_number_simple_int.json @@ -0,0 +1 @@ +[123] \ No newline at end of file diff --git a/resources/json/y_number_simple_real.json b/resources/json/y_number_simple_real.json new file mode 100644 index 0000000..b02878e --- /dev/null +++ b/resources/json/y_number_simple_real.json @@ -0,0 +1 @@ +[123.456789] \ No newline at end of file diff --git a/resources/json/y_object.json b/resources/json/y_object.json new file mode 100755 index 0000000..78262ed --- /dev/null +++ b/resources/json/y_object.json @@ -0,0 +1 @@ +{"asd":"sdf", "dfg":"fgh"} \ No newline at end of file diff --git a/resources/json/y_object_basic.json b/resources/json/y_object_basic.json new file mode 100755 index 0000000..646bbe7 --- /dev/null +++ b/resources/json/y_object_basic.json @@ -0,0 +1 @@ +{"asd":"sdf"} \ No newline at end of file diff --git a/resources/json/y_object_duplicated_key.json b/resources/json/y_object_duplicated_key.json new file mode 100755 index 0000000..bbc2e1c --- /dev/null +++ b/resources/json/y_object_duplicated_key.json @@ -0,0 +1 @@ +{"a":"b","a":"c"} \ No newline at end of file diff --git a/resources/json/y_object_duplicated_key_and_value.json b/resources/json/y_object_duplicated_key_and_value.json new file mode 100755 index 0000000..211581c --- /dev/null +++ b/resources/json/y_object_duplicated_key_and_value.json @@ -0,0 +1 @@ +{"a":"b","a":"b"} \ No newline at end of file diff --git a/resources/json/y_object_empty.json b/resources/json/y_object_empty.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/resources/json/y_object_empty.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/resources/json/y_object_empty_key.json b/resources/json/y_object_empty_key.json new file mode 100755 index 0000000..c0013d3 --- /dev/null +++ b/resources/json/y_object_empty_key.json @@ -0,0 +1 @@ +{"":0} \ No newline at end of file diff --git a/resources/json/y_object_escaped_null_in_key.json b/resources/json/y_object_escaped_null_in_key.json new file mode 100644 index 0000000..593f0f6 --- /dev/null +++ b/resources/json/y_object_escaped_null_in_key.json @@ -0,0 +1 @@ +{"foo\u0000bar": 42} \ No newline at end of file diff --git a/resources/json/y_object_extreme_numbers.json b/resources/json/y_object_extreme_numbers.json new file mode 100644 index 0000000..a0d3531 --- /dev/null +++ b/resources/json/y_object_extreme_numbers.json @@ -0,0 +1 @@ +{ "min": -1.0e+28, "max": 1.0e+28 } \ No newline at end of file diff --git a/resources/json/y_object_long_strings.json b/resources/json/y_object_long_strings.json new file mode 100644 index 0000000..bdc4a08 --- /dev/null +++ b/resources/json/y_object_long_strings.json @@ -0,0 +1 @@ +{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"} \ No newline at end of file diff --git a/resources/json/y_object_simple.json b/resources/json/y_object_simple.json new file mode 100644 index 0000000..dacac91 --- /dev/null +++ b/resources/json/y_object_simple.json @@ -0,0 +1 @@ +{"a":[]} \ No newline at end of file diff --git a/resources/json/y_object_string_unicode.json b/resources/json/y_object_string_unicode.json new file mode 100644 index 0000000..8effdb2 --- /dev/null +++ b/resources/json/y_object_string_unicode.json @@ -0,0 +1 @@ +{"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" } \ No newline at end of file diff --git a/resources/json/y_object_with_newlines.json b/resources/json/y_object_with_newlines.json new file mode 100644 index 0000000..246ec6b --- /dev/null +++ b/resources/json/y_object_with_newlines.json @@ -0,0 +1,3 @@ +{ +"a": "b" +} \ No newline at end of file diff --git a/resources/json/y_string_1_2_3_bytes_UTF-8_sequences.json b/resources/json/y_string_1_2_3_bytes_UTF-8_sequences.json new file mode 100755 index 0000000..9967dde --- /dev/null +++ b/resources/json/y_string_1_2_3_bytes_UTF-8_sequences.json @@ -0,0 +1 @@ +["\u0060\u012a\u12AB"] \ No newline at end of file diff --git a/resources/json/y_string_accepted_surrogate_pair.json b/resources/json/y_string_accepted_surrogate_pair.json new file mode 100755 index 0000000..996875c --- /dev/null +++ b/resources/json/y_string_accepted_surrogate_pair.json @@ -0,0 +1 @@ +["\uD801\udc37"] \ No newline at end of file diff --git a/resources/json/y_string_accepted_surrogate_pairs.json b/resources/json/y_string_accepted_surrogate_pairs.json new file mode 100755 index 0000000..3401021 --- /dev/null +++ b/resources/json/y_string_accepted_surrogate_pairs.json @@ -0,0 +1 @@ +["\ud83d\ude39\ud83d\udc8d"] \ No newline at end of file diff --git a/resources/json/y_string_allowed_escapes.json b/resources/json/y_string_allowed_escapes.json new file mode 100644 index 0000000..7f49553 --- /dev/null +++ b/resources/json/y_string_allowed_escapes.json @@ -0,0 +1 @@ +["\"\\\/\b\f\n\r\t"] \ No newline at end of file diff --git a/resources/json/y_string_backslash_and_u_escaped_zero.json b/resources/json/y_string_backslash_and_u_escaped_zero.json new file mode 100755 index 0000000..d4439ed --- /dev/null +++ b/resources/json/y_string_backslash_and_u_escaped_zero.json @@ -0,0 +1 @@ +["\\u0000"] \ No newline at end of file diff --git a/resources/json/y_string_backslash_doublequotes.json b/resources/json/y_string_backslash_doublequotes.json new file mode 100644 index 0000000..ae03243 --- /dev/null +++ b/resources/json/y_string_backslash_doublequotes.json @@ -0,0 +1 @@ +["\""] \ No newline at end of file diff --git a/resources/json/y_string_comments.json b/resources/json/y_string_comments.json new file mode 100644 index 0000000..2260c20 --- /dev/null +++ b/resources/json/y_string_comments.json @@ -0,0 +1 @@ +["a/*b*/c/*d//e"] \ No newline at end of file diff --git a/resources/json/y_string_double_escape_a.json b/resources/json/y_string_double_escape_a.json new file mode 100644 index 0000000..6715d6f --- /dev/null +++ b/resources/json/y_string_double_escape_a.json @@ -0,0 +1 @@ +["\\a"] \ No newline at end of file diff --git a/resources/json/y_string_double_escape_n.json b/resources/json/y_string_double_escape_n.json new file mode 100644 index 0000000..44ca56c --- /dev/null +++ b/resources/json/y_string_double_escape_n.json @@ -0,0 +1 @@ +["\\n"] \ No newline at end of file diff --git a/resources/json/y_string_escaped_control_character.json b/resources/json/y_string_escaped_control_character.json new file mode 100644 index 0000000..5b014a9 --- /dev/null +++ b/resources/json/y_string_escaped_control_character.json @@ -0,0 +1 @@ +["\u0012"] \ No newline at end of file diff --git a/resources/json/y_string_escaped_noncharacter.json b/resources/json/y_string_escaped_noncharacter.json new file mode 100755 index 0000000..2ff52e2 --- /dev/null +++ b/resources/json/y_string_escaped_noncharacter.json @@ -0,0 +1 @@ +["\uFFFF"] \ No newline at end of file diff --git a/resources/json/y_string_in_array.json b/resources/json/y_string_in_array.json new file mode 100755 index 0000000..21d7ae4 --- /dev/null +++ b/resources/json/y_string_in_array.json @@ -0,0 +1 @@ +["asd"] \ No newline at end of file diff --git a/resources/json/y_string_in_array_with_leading_space.json b/resources/json/y_string_in_array_with_leading_space.json new file mode 100755 index 0000000..9e1887c --- /dev/null +++ b/resources/json/y_string_in_array_with_leading_space.json @@ -0,0 +1 @@ +[ "asd"] \ No newline at end of file diff --git a/resources/json/y_string_last_surrogates_1_and_2.json b/resources/json/y_string_last_surrogates_1_and_2.json new file mode 100644 index 0000000..3919cef --- /dev/null +++ b/resources/json/y_string_last_surrogates_1_and_2.json @@ -0,0 +1 @@ +["\uDBFF\uDFFF"] \ No newline at end of file diff --git a/resources/json/y_string_nbsp_uescaped.json b/resources/json/y_string_nbsp_uescaped.json new file mode 100644 index 0000000..2085ab1 --- /dev/null +++ b/resources/json/y_string_nbsp_uescaped.json @@ -0,0 +1 @@ +["new\u00A0line"] \ No newline at end of file diff --git a/resources/json/y_string_nonCharacterInUTF-8_U+10FFFF.json b/resources/json/y_string_nonCharacterInUTF-8_U+10FFFF.json new file mode 100755 index 0000000..059e4d9 --- /dev/null +++ b/resources/json/y_string_nonCharacterInUTF-8_U+10FFFF.json @@ -0,0 +1 @@ +["􏿿"] \ No newline at end of file diff --git a/resources/json/y_string_nonCharacterInUTF-8_U+FFFF.json b/resources/json/y_string_nonCharacterInUTF-8_U+FFFF.json new file mode 100755 index 0000000..4c913bd --- /dev/null +++ b/resources/json/y_string_nonCharacterInUTF-8_U+FFFF.json @@ -0,0 +1 @@ +["￿"] \ No newline at end of file diff --git a/resources/json/y_string_null_escape.json b/resources/json/y_string_null_escape.json new file mode 100644 index 0000000..c1ad844 --- /dev/null +++ b/resources/json/y_string_null_escape.json @@ -0,0 +1 @@ +["\u0000"] \ No newline at end of file diff --git a/resources/json/y_string_one-byte-utf-8.json b/resources/json/y_string_one-byte-utf-8.json new file mode 100644 index 0000000..1571859 --- /dev/null +++ b/resources/json/y_string_one-byte-utf-8.json @@ -0,0 +1 @@ +["\u002c"] \ No newline at end of file diff --git a/resources/json/y_string_pi.json b/resources/json/y_string_pi.json new file mode 100644 index 0000000..9df11ae --- /dev/null +++ b/resources/json/y_string_pi.json @@ -0,0 +1 @@ +["π"] \ No newline at end of file diff --git a/resources/json/y_string_reservedCharacterInUTF-8_U+1BFFF.json b/resources/json/y_string_reservedCharacterInUTF-8_U+1BFFF.json new file mode 100755 index 0000000..10a33a1 --- /dev/null +++ b/resources/json/y_string_reservedCharacterInUTF-8_U+1BFFF.json @@ -0,0 +1 @@ +["𛿿"] \ No newline at end of file diff --git a/resources/json/y_string_simple_ascii.json b/resources/json/y_string_simple_ascii.json new file mode 100644 index 0000000..8cadf7d --- /dev/null +++ b/resources/json/y_string_simple_ascii.json @@ -0,0 +1 @@ +["asd "] \ No newline at end of file diff --git a/resources/json/y_string_space.json b/resources/json/y_string_space.json new file mode 100644 index 0000000..efd782c --- /dev/null +++ b/resources/json/y_string_space.json @@ -0,0 +1 @@ +" " \ No newline at end of file diff --git a/resources/json/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json b/resources/json/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json new file mode 100755 index 0000000..7620b66 --- /dev/null +++ b/resources/json/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json @@ -0,0 +1 @@ +["\uD834\uDd1e"] \ No newline at end of file diff --git a/resources/json/y_string_three-byte-utf-8.json b/resources/json/y_string_three-byte-utf-8.json new file mode 100644 index 0000000..108f1d6 --- /dev/null +++ b/resources/json/y_string_three-byte-utf-8.json @@ -0,0 +1 @@ +["\u0821"] \ No newline at end of file diff --git a/resources/json/y_string_two-byte-utf-8.json b/resources/json/y_string_two-byte-utf-8.json new file mode 100644 index 0000000..461503c --- /dev/null +++ b/resources/json/y_string_two-byte-utf-8.json @@ -0,0 +1 @@ +["\u0123"] \ No newline at end of file diff --git a/resources/json/y_string_u+2028_line_sep.json b/resources/json/y_string_u+2028_line_sep.json new file mode 100755 index 0000000..897b602 --- /dev/null +++ b/resources/json/y_string_u+2028_line_sep.json @@ -0,0 +1 @@ +["
"] \ No newline at end of file diff --git a/resources/json/y_string_u+2029_par_sep.json b/resources/json/y_string_u+2029_par_sep.json new file mode 100755 index 0000000..8cd998c --- /dev/null +++ b/resources/json/y_string_u+2029_par_sep.json @@ -0,0 +1 @@ +["
"] \ No newline at end of file diff --git a/resources/json/y_string_uEscape.json b/resources/json/y_string_uEscape.json new file mode 100755 index 0000000..f7b41a0 --- /dev/null +++ b/resources/json/y_string_uEscape.json @@ -0,0 +1 @@ +["\u0061\u30af\u30EA\u30b9"] \ No newline at end of file diff --git a/resources/json/y_string_uescaped_newline.json b/resources/json/y_string_uescaped_newline.json new file mode 100644 index 0000000..3a5a220 --- /dev/null +++ b/resources/json/y_string_uescaped_newline.json @@ -0,0 +1 @@ +["new\u000Aline"] \ No newline at end of file diff --git a/resources/json/y_string_unescaped_char_delete.json b/resources/json/y_string_unescaped_char_delete.json new file mode 100755 index 0000000..7d064f4 --- /dev/null +++ b/resources/json/y_string_unescaped_char_delete.json @@ -0,0 +1 @@ +[""] \ No newline at end of file diff --git a/resources/json/y_string_unicode.json b/resources/json/y_string_unicode.json new file mode 100644 index 0000000..3598095 --- /dev/null +++ b/resources/json/y_string_unicode.json @@ -0,0 +1 @@ +["\uA66D"] \ No newline at end of file diff --git a/resources/json/y_string_unicodeEscapedBackslash.json b/resources/json/y_string_unicodeEscapedBackslash.json new file mode 100755 index 0000000..0bb3b51 --- /dev/null +++ b/resources/json/y_string_unicodeEscapedBackslash.json @@ -0,0 +1 @@ +["\u005C"] \ No newline at end of file diff --git a/resources/json/y_string_unicode_2.json b/resources/json/y_string_unicode_2.json new file mode 100644 index 0000000..a7dcb97 --- /dev/null +++ b/resources/json/y_string_unicode_2.json @@ -0,0 +1 @@ +["⍂㈴⍂"] \ No newline at end of file diff --git a/resources/json/y_string_unicode_U+10FFFE_nonchar.json b/resources/json/y_string_unicode_U+10FFFE_nonchar.json new file mode 100644 index 0000000..9a8370b --- /dev/null +++ b/resources/json/y_string_unicode_U+10FFFE_nonchar.json @@ -0,0 +1 @@ +["\uDBFF\uDFFE"] \ No newline at end of file diff --git a/resources/json/y_string_unicode_U+1FFFE_nonchar.json b/resources/json/y_string_unicode_U+1FFFE_nonchar.json new file mode 100644 index 0000000..c51f8ae --- /dev/null +++ b/resources/json/y_string_unicode_U+1FFFE_nonchar.json @@ -0,0 +1 @@ +["\uD83F\uDFFE"] \ No newline at end of file diff --git a/resources/json/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json b/resources/json/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json new file mode 100644 index 0000000..626d5f8 --- /dev/null +++ b/resources/json/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json @@ -0,0 +1 @@ +["\u200B"] \ No newline at end of file diff --git a/resources/json/y_string_unicode_U+2064_invisible_plus.json b/resources/json/y_string_unicode_U+2064_invisible_plus.json new file mode 100644 index 0000000..1e23972 --- /dev/null +++ b/resources/json/y_string_unicode_U+2064_invisible_plus.json @@ -0,0 +1 @@ +["\u2064"] \ No newline at end of file diff --git a/resources/json/y_string_unicode_U+FDD0_nonchar.json b/resources/json/y_string_unicode_U+FDD0_nonchar.json new file mode 100644 index 0000000..18ef151 --- /dev/null +++ b/resources/json/y_string_unicode_U+FDD0_nonchar.json @@ -0,0 +1 @@ +["\uFDD0"] \ No newline at end of file diff --git a/resources/json/y_string_unicode_U+FFFE_nonchar.json b/resources/json/y_string_unicode_U+FFFE_nonchar.json new file mode 100644 index 0000000..13d261f --- /dev/null +++ b/resources/json/y_string_unicode_U+FFFE_nonchar.json @@ -0,0 +1 @@ +["\uFFFE"] \ No newline at end of file diff --git a/resources/json/y_string_unicode_escaped_double_quote.json b/resources/json/y_string_unicode_escaped_double_quote.json new file mode 100755 index 0000000..4e62578 --- /dev/null +++ b/resources/json/y_string_unicode_escaped_double_quote.json @@ -0,0 +1 @@ +["\u0022"] \ No newline at end of file diff --git a/resources/json/y_string_utf8.json b/resources/json/y_string_utf8.json new file mode 100644 index 0000000..4087843 --- /dev/null +++ b/resources/json/y_string_utf8.json @@ -0,0 +1 @@ +["€𝄞"] \ No newline at end of file diff --git a/resources/json/y_string_with_del_character.json b/resources/json/y_string_with_del_character.json new file mode 100755 index 0000000..8bd2490 --- /dev/null +++ b/resources/json/y_string_with_del_character.json @@ -0,0 +1 @@ +["aa"] \ No newline at end of file diff --git a/resources/json/y_structure_lonely_false.json b/resources/json/y_structure_lonely_false.json new file mode 100644 index 0000000..02e4a84 --- /dev/null +++ b/resources/json/y_structure_lonely_false.json @@ -0,0 +1 @@ +false \ No newline at end of file diff --git a/resources/json/y_structure_lonely_int.json b/resources/json/y_structure_lonely_int.json new file mode 100755 index 0000000..f70d7bb --- /dev/null +++ b/resources/json/y_structure_lonely_int.json @@ -0,0 +1 @@ +42 \ No newline at end of file diff --git a/resources/json/y_structure_lonely_negative_real.json b/resources/json/y_structure_lonely_negative_real.json new file mode 100755 index 0000000..b5135a2 --- /dev/null +++ b/resources/json/y_structure_lonely_negative_real.json @@ -0,0 +1 @@ +-0.1 \ No newline at end of file diff --git a/resources/json/y_structure_lonely_null.json b/resources/json/y_structure_lonely_null.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/resources/json/y_structure_lonely_null.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/resources/json/y_structure_lonely_string.json b/resources/json/y_structure_lonely_string.json new file mode 100755 index 0000000..b6e982c --- /dev/null +++ b/resources/json/y_structure_lonely_string.json @@ -0,0 +1 @@ +"asd" \ No newline at end of file diff --git a/resources/json/y_structure_lonely_true.json b/resources/json/y_structure_lonely_true.json new file mode 100755 index 0000000..f32a580 --- /dev/null +++ b/resources/json/y_structure_lonely_true.json @@ -0,0 +1 @@ +true \ No newline at end of file diff --git a/resources/json/y_structure_string_empty.json b/resources/json/y_structure_string_empty.json new file mode 100644 index 0000000..3cc762b --- /dev/null +++ b/resources/json/y_structure_string_empty.json @@ -0,0 +1 @@ +"" \ No newline at end of file diff --git a/resources/json/y_structure_trailing_newline.json b/resources/json/y_structure_trailing_newline.json new file mode 100644 index 0000000..0c3426d --- /dev/null +++ b/resources/json/y_structure_trailing_newline.json @@ -0,0 +1 @@ +["a"] diff --git a/resources/json/y_structure_true_in_array.json b/resources/json/y_structure_true_in_array.json new file mode 100644 index 0000000..de601e3 --- /dev/null +++ b/resources/json/y_structure_true_in_array.json @@ -0,0 +1 @@ +[true] \ No newline at end of file diff --git a/resources/json/y_structure_whitespace_array.json b/resources/json/y_structure_whitespace_array.json new file mode 100644 index 0000000..2bedf7f --- /dev/null +++ b/resources/json/y_structure_whitespace_array.json @@ -0,0 +1 @@ + [] \ No newline at end of file diff --git a/src/server/refresh/docker.rs b/src/server/refresh/docker.rs index 188d3c3..1085e6d 100644 --- a/src/server/refresh/docker.rs +++ b/src/server/refresh/docker.rs @@ -87,6 +87,20 @@ enum JsonValue { Array(Vec), } +/// If the characters at `chars` match the characters in `prefix`, consume +/// those and return true. Otherwise, return false and do not advance the +/// iterator. +fn matches(chars: &mut std::str::Chars, prefix: &str) -> bool { + let backup = chars.clone(); + for c in prefix.chars() { + if chars.next() != Some(c) { + *chars = backup; + return false; + } + } + true +} + impl JsonValue { pub fn parse(blob: &[u8]) -> Result { Self::parse_impl(blob).with_context(|| { @@ -191,8 +205,9 @@ impl JsonValue { bail!("Unterminated string at {i}"); } assert_eq!(blob[i], b'"'); - let mut chars = - std::str::from_utf8(&blob[start..i])?.chars(); + + let source = String::from_utf8_lossy(&blob[start..i]); + let mut chars = source.chars(); i += 1; // Consume the final quote. let mut value = String::new(); @@ -201,25 +216,52 @@ impl JsonValue { match chars.next().expect("mismatched escape") { '"' => value.push('"'), '\\' => value.push('\\'), + '/' => value.push('/'), 'b' => value.push('\x08'), 'f' => value.push('\x0C'), 'n' => value.push('\n'), 'r' => value.push('\r'), 't' => value.push('\t'), 'u' => { - // 4 hex + // 4 hex to a 16bit number. + // + // This is complicated because it might + // be the first part of a surrogate pair, + // which is a utf-16 thing that we should + // decode properly. (Hard to think of an + // acceptable way to cheat this.) So we + // buffer all codes we can find into a + // vector of u16s and then use + // std::char's `decode_utf16` to get the + // final string. We could do this with + // fewer allocations if we cared more. let mut temp = String::with_capacity(4); - for _ in 0..4 { - let Some(c) = chars.next() else { - bail!("not enough chars in unicode escape") - }; - temp.push(c); + let mut utf16 = Vec::new(); + loop { + temp.clear(); + for _ in 0..4 { + let Some(c) = chars.next() else { + bail!("not enough chars in unicode escape") + }; + temp.push(c); + } + let code = + u16::from_str_radix(&temp, 16)?; + utf16.push(code); + + // `matches` only consumes on a match... + if !matches(&mut chars, "\\u") { + break; + } } - let code = u32::from_str_radix(&temp, 16)?; - let Some(c) = char::from_u32(code) else { - bail!("invalid escape code {temp}") - }; - value.push(c); + + value.extend( + char::decode_utf16(utf16).map(|r| { + r.unwrap_or( + char::REPLACEMENT_CHARACTER, + ) + }), + ); } _ => bail!("Invalid json escape"), } @@ -348,7 +390,7 @@ mod test { use super::*; #[test] - pub fn test_json_decode_basic() { + pub fn json_decode_basic() { let cases: Vec<(&str, JsonValue)> = vec![ ("12", JsonValue::Number(12.0)), ("12.7", JsonValue::Number(12.7)), @@ -370,7 +412,7 @@ mod test { } #[test] - pub fn test_json_decode_array() { + pub fn json_decode_array() { let result = JsonValue::parse(b"[1, true, \"foo\", null]").unwrap(); let JsonValue::Array(result) = result else { panic!("Expected an array"); @@ -383,13 +425,13 @@ mod test { } #[test] - pub fn test_json_decode_array_empty() { + pub fn json_decode_array_empty() { let result = JsonValue::parse(b"[]").unwrap(); assert_eq!(result, JsonValue::Array(vec![])); } #[test] - pub fn test_json_decode_array_nested() { + pub fn json_decode_array_nested() { let result = JsonValue::parse(b"[1, [2, 3], 4]").unwrap(); assert_eq!( result, @@ -405,7 +447,7 @@ mod test { } #[test] - pub fn test_json_decode_object() { + pub fn json_decode_object() { let result = JsonValue::parse( b"{\"a\": 1.0, \"b\": [2.0, 3.0], \"c\": {\"d\": 4.0}}", ) @@ -433,7 +475,34 @@ mod test { } #[test] - pub fn test_json_decode_docker() { + pub fn json_decode_test_files() { + use std::path::{Path, PathBuf}; + fn is_json(p: &Path) -> bool { + p.is_file() && p.extension().map(|s| s == "json").unwrap_or(false) + } + + let manifest_dir: PathBuf = + [env!("CARGO_MANIFEST_DIR"), "resources", "json"] + .iter() + .collect(); + + for file in manifest_dir.read_dir().unwrap().flatten() { + let path = file.path(); + if !is_json(&path) { + continue; + } + + let json = std::fs::read(&path).expect("Unable to read input file"); + let path = path.display(); + if let Err(err) = JsonValue::parse(&json) { + panic!("Unable to parse {path}: {err:?}"); + } + eprintln!("Parsed {path} successfully"); + } + } + + #[test] + pub fn json_decode_docker() { use pretty_assertions::assert_eq; // This is the example container response from docker