Unverified Commit 63c2c62f authored by Niels Lohmann's avatar Niels Lohmann

🔨 changed call from "not good()" to "fail()" #493

Also merged develop into this feature branch.
parents 4e498298 95474e42
...@@ -78,13 +78,13 @@ matrix: ...@@ -78,13 +78,13 @@ matrix:
env: env:
- COMPILER=g++-4.9 - COMPILER=g++-4.9
- SPECIAL=no_exceptions - SPECIAL=no_exceptions
- TEST_PATTERN=-e \"*\"
addons: addons:
apt: apt:
sources: ['ubuntu-toolchain-r-test'] sources: ['ubuntu-toolchain-r-test']
packages: [g++-4.9, cppcheck] packages: [g++-4.9, cppcheck]
before_script: after_success:
- CPPFLAGS="-DJSON_NOEXCEPTION" make - make clean
- CPPFLAGS="-DJSON_NOEXCEPTION" make check TEST_PATTERN="-e \"*\""
# Coveralls (http://gronlier.fr/blog/2015/01/adding-code-coverage-to-your-c-project/) # Coveralls (http://gronlier.fr/blog/2015/01/adding-code-coverage-to-your-c-project/)
......
...@@ -49,6 +49,7 @@ doctest: ...@@ -49,6 +49,7 @@ doctest:
# -Wno-documentation-unknown-command: code uses user-defined commands like @complexity # -Wno-documentation-unknown-command: code uses user-defined commands like @complexity
# -Wno-exit-time-destructors: warning in Catch code # -Wno-exit-time-destructors: warning in Catch code
# -Wno-keyword-macro: unit-tests use "#define private public" # -Wno-keyword-macro: unit-tests use "#define private public"
# -Wno-weak-vtables: exception class is defined inline, but has virtual method
# -Wno-range-loop-analysis: iterator_wrapper tests tests "for(const auto i...)" # -Wno-range-loop-analysis: iterator_wrapper tests tests "for(const auto i...)"
pedantic: pedantic:
$(MAKE) json_unit CXXFLAGS="\ $(MAKE) json_unit CXXFLAGS="\
...@@ -58,6 +59,7 @@ pedantic: ...@@ -58,6 +59,7 @@ pedantic:
-Wno-documentation-unknown-command \ -Wno-documentation-unknown-command \
-Wno-exit-time-destructors \ -Wno-exit-time-destructors \
-Wno-keyword-macro \ -Wno-keyword-macro \
-Wno-weak-vtables \
-Wno-range-loop-analysis" -Wno-range-loop-analysis"
......
...@@ -58,6 +58,9 @@ doxygen: create_output create_links ...@@ -58,6 +58,9 @@ doxygen: create_output create_links
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html $(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html
$(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html $(SED) -i 's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer >@@g' html/*.html
$(SED) -i 's@&lt;&#160;ObjectType,&#160;ArrayType,&#160;StringType,&#160;BooleanType,&#160;NumberIntegerType,&#160;NumberUnsignedType,&#160;NumberFloatType,&#160;AllocatorType&#160;JSONSerializer&#160;&gt;@@g' html/*.html $(SED) -i 's@&lt;&#160;ObjectType,&#160;ArrayType,&#160;StringType,&#160;BooleanType,&#160;NumberIntegerType,&#160;NumberUnsignedType,&#160;NumberFloatType,&#160;AllocatorType&#160;JSONSerializer&#160;&gt;@@g' html/*.html
$(SED) -i 's@template&lt;template&lt; typename U, typename V, typename... Args &gt; class ObjectType = std::map, template&lt; typename U, typename... Args &gt; class ArrayType = std::vector, class StringType = std::string, class BooleanType = bool, class NumberIntegerType = std::int64_t, class NumberUnsignedType = std::uint64_t, class NumberFloatType = double, template&lt; typename U &gt; class AllocatorType = std::allocator, template&lt; typename T, typename SFINAE=void &gt; class JSONSerializer = adl_serializer&gt;@@g' html/*.html
$(SED) -i 's@&lt; ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer &gt;@@g' html/*.html
$(SED) -i 's@&lt;&#160;ObjectType,&#160;ArrayType,&#160;StringType,&#160;BooleanType,&#160;NumberIntegerType,&#160;NumberUnsignedType,&#160;NumberFloatType,&#160;AllocatorType,&#160;JSONSerializer&#160;&gt;@@g' html/*.html
upload: clean doxygen check_output upload: clean doxygen check_output
cd html ; ../scripts/git-update-ghpages nlohmann/json cd html ; ../scripts/git-update-ghpages nlohmann/json
......
...@@ -21,13 +21,27 @@ int main() ...@@ -21,13 +21,27 @@ int main()
// output changed array // output changed array
std::cout << object << '\n'; std::cout << object << '\n';
// try to write at a nonexisting key
// exception type_error.304
try
{
// use at() on a non-object type
json str = "I am a string";
str.at("the good") = "Another string";
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
// exception out_of_range.401
try try
{ {
// try to write at a nonexisting key
object.at("the fast") = "il rapido"; object.at("the fast") = "il rapido";
} }
catch (std::out_of_range& e) catch (json::out_of_range& e)
{ {
std::cout << "out of range: " << e.what() << '\n'; std::cout << e.what() << '\n';
} }
} }
<a target="_blank" href="http://melpon.org/wandbox/permlink/tb5CaFfsMWpAvi7m"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/8ldtT0NOhidn0fOA"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
"il brutto" "il brutto"
{"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"} {"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"}
out of range: key 'the fast' not found [json.exception.type_error.304] cannot use at() with string
[json.exception.out_of_range.403] key 'the fast' not found
"il brutto"
{"the bad":"il cattivo","the good":"il buono","the ugly":"il brutto"}
[json.exception.out_of_range.403] key 'the fast' not found
...@@ -15,12 +15,26 @@ int main() ...@@ -15,12 +15,26 @@ int main()
// output element with key "the ugly" // output element with key "the ugly"
std::cout << object.at("the ugly") << '\n'; std::cout << object.at("the ugly") << '\n';
// try to read from a nonexisting key
// exception type_error.304
try
{
// use at() on a non-object type
const json str = "I am a string";
std::cout << str.at("the good") << '\n';
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
// exception out_of_range.401
try try
{ {
// try to read from a nonexisting key
std::cout << object.at("the fast") << '\n'; std::cout << object.at("the fast") << '\n';
} }
catch (std::out_of_range) catch (json::out_of_range)
{ {
std::cout << "out of range" << '\n'; std::cout << "out of range" << '\n';
} }
......
<a target="_blank" href="http://melpon.org/wandbox/permlink/NFG86H5khRUePc1s"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/nfmFWMaJJHFJ7eVK"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
"il brutto" "il brutto"
[json.exception.type_error.304] cannot use at() with string
out of range out of range
...@@ -16,13 +16,27 @@ int main() ...@@ -16,13 +16,27 @@ int main()
// output changed array // output changed array
std::cout << array << '\n'; std::cout << array << '\n';
// try to write beyond the array limit
// exception type_error.304
try
{
// use at() on a non-array type
json str = "I am a string";
str.at(0) = "Another string";
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
// exception out_of_range.401
try try
{ {
// try to write beyond the array limit
array.at(5) = "sixth"; array.at(5) = "sixth";
} }
catch (std::out_of_range& e) catch (json::out_of_range& e)
{ {
std::cout << "out of range: " << e.what() << '\n'; std::cout << e.what() << '\n';
} }
} }
<a target="_blank" href="http://melpon.org/wandbox/permlink/R7z2SB2rMdFQ9XtR"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/8UnQY256zGX2Lx6d"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
"third" "third"
["first","second","third","fourth"] ["first","second","third","fourth"]
out of range: array index 5 is out of range [json.exception.type_error.304] cannot use at() with string
[json.exception.out_of_range.401] array index 5 is out of range
...@@ -5,18 +5,32 @@ using json = nlohmann::json; ...@@ -5,18 +5,32 @@ using json = nlohmann::json;
int main() int main()
{ {
// create JSON array // create JSON array
json array = {"first", "2nd", "third", "fourth"}; const json array = {"first", "2nd", "third", "fourth"};
// output element at index 2 (third element) // output element at index 2 (third element)
std::cout << array.at(2) << '\n'; std::cout << array.at(2) << '\n';
// try to read beyond the array limit
// exception type_error.304
try
{
// use at() on a non-array type
const json str = "I am a string";
std::cout << str.at(0) << '\n';
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
// exception out_of_range.401
try try
{ {
// try to read beyond the array limit
std::cout << array.at(5) << '\n'; std::cout << array.at(5) << '\n';
} }
catch (std::out_of_range) catch (json::out_of_range& e)
{ {
std::cout << "out of range" << '\n'; std::cout << e.what() << '\n';
} }
} }
<a target="_blank" href="http://melpon.org/wandbox/permlink/L1bMeiN6nYm7JrvA"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/U1fv6LY7xZOAuSBs"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
"third" "third"
out of range [json.exception.type_error.304] cannot use at() with string
[json.exception.out_of_range.401] array index 5 is out of range
...@@ -32,4 +32,60 @@ int main() ...@@ -32,4 +32,60 @@ int main()
j.at("/array/1"_json_pointer) = 21; j.at("/array/1"_json_pointer) = 21;
// output the changed array // output the changed array
std::cout << j["array"] << '\n'; std::cout << j["array"] << '\n';
// out_of_range.106
try
{
// try to use an array index with leading '0'
json::reference ref = j.at("/array/01"_json_pointer);
}
catch (json::parse_error& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.109
try
{
// try to use an array index that is not a number
json::reference ref = j.at("/array/one"_json_pointer);
}
catch (json::parse_error& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.401
try
{
// try to use a an invalid array index
json::reference ref = j.at("/array/4"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.402
try
{
// try to use the array index '-'
json::reference ref = j.at("/array/-"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.404
try
{
// try to use a JSON pointer that cannot be resolved
json::reference ref = j.at("/number/foo"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
} }
<a target="_blank" href="http://melpon.org/wandbox/permlink/NDSjglHZIjIZ0Uxg"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/Fy2xBfZMols2DUQC"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
...@@ -4,3 +4,8 @@ ...@@ -4,3 +4,8 @@
2 2
"bar" "bar"
[1,21] [1,21]
[json.exception.parse_error.106] parse error: array index '01' must not begin with '0'
[json.exception.parse_error.109] parse error: array index 'one' is not a number
[json.exception.out_of_range.401] array index 4 is out of range
[json.exception.out_of_range.402] array index '-' (2) is out of range
[json.exception.out_of_range.404] unresolved reference token 'foo'
...@@ -5,7 +5,7 @@ using json = nlohmann::json; ...@@ -5,7 +5,7 @@ using json = nlohmann::json;
int main() int main()
{ {
// create a JSON value // create a JSON value
json j = const json j =
{ {
{"number", 1}, {"string", "foo"}, {"array", {1, 2}} {"number", 1}, {"string", "foo"}, {"array", {1, 2}}
}; };
...@@ -20,4 +20,48 @@ int main() ...@@ -20,4 +20,48 @@ int main()
std::cout << j.at("/array"_json_pointer) << '\n'; std::cout << j.at("/array"_json_pointer) << '\n';
// output element with JSON pointer "/array/1" // output element with JSON pointer "/array/1"
std::cout << j.at("/array/1"_json_pointer) << '\n'; std::cout << j.at("/array/1"_json_pointer) << '\n';
// out_of_range.109
try
{
// try to use an array index that is not a number
json::const_reference ref = j.at("/array/one"_json_pointer);
}
catch (json::parse_error& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.401
try
{
// try to use a an invalid array index
json::const_reference ref = j.at("/array/4"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.402
try
{
// try to use the array index '-'
json::const_reference ref = j.at("/array/-"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
// out_of_range.404
try
{
// try to use a JSON pointer that cannot be resolved
json::const_reference ref = j.at("/number/foo"_json_pointer);
}
catch (json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
} }
<a target="_blank" href="http://melpon.org/wandbox/permlink/OuLYiMJ3pgyOHupb"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/WxhV3mL9YX8FJonk"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
...@@ -2,3 +2,7 @@ ...@@ -2,3 +2,7 @@
"foo" "foo"
[1,2] [1,2]
2 2
[json.exception.parse_error.109] parse error: array index 'one' is not a number
[json.exception.out_of_range.401] array index 4 is out of range
[json.exception.out_of_range.402] array index '-' (2) is out of range
[json.exception.out_of_range.404] unresolved reference token 'foo'
...@@ -5,7 +5,6 @@ using json = nlohmann::json; ...@@ -5,7 +5,6 @@ using json = nlohmann::json;
int main() int main()
{ {
// create JSON values // create JSON values
json j_null;
json j_boolean = true; json j_boolean = true;
json j_number_integer = 17; json j_number_integer = 17;
json j_number_float = 23.42; json j_number_float = 23.42;
...@@ -16,7 +15,6 @@ int main() ...@@ -16,7 +15,6 @@ int main()
json j_string = "Hello, world"; json j_string = "Hello, world";
// call back() // call back()
//std::cout << j_null.back() << '\n'; // would throw
std::cout << j_boolean.back() << '\n'; std::cout << j_boolean.back() << '\n';
std::cout << j_number_integer.back() << '\n'; std::cout << j_number_integer.back() << '\n';
std::cout << j_number_float.back() << '\n'; std::cout << j_number_float.back() << '\n';
...@@ -25,4 +23,15 @@ int main() ...@@ -25,4 +23,15 @@ int main()
std::cout << j_array.back() << '\n'; std::cout << j_array.back() << '\n';
//std::cout << j_array_empty.back() << '\n'; // undefined behavior //std::cout << j_array_empty.back() << '\n'; // undefined behavior
std::cout << j_string.back() << '\n'; std::cout << j_string.back() << '\n';
// back() called on a null value
try
{
json j_null;
j_null.back();
}
catch (json::invalid_iterator& e)
{
std::cout << e.what() << '\n';
}
} }
<a target="_blank" href="http://melpon.org/wandbox/permlink/nPVnBcHf8nrNpGOJ"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/CAv4NNr4D1FJhhUv"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
...@@ -4,3 +4,4 @@ true ...@@ -4,3 +4,4 @@ true
2 2
16 16
"Hello, world" "Hello, world"
[json.exception.invalid_iterator.214] cannot get value
...@@ -18,4 +18,14 @@ int main() ...@@ -18,4 +18,14 @@ int main()
std::cout << j_array_range << '\n'; std::cout << j_array_range << '\n';
std::cout << j_number_range << '\n'; std::cout << j_number_range << '\n';
std::cout << j_object_range << '\n'; std::cout << j_object_range << '\n';
// example for an exception
try
{
json j_invalid(j_number.begin() + 1, j_number.end());
}
catch (json::invalid_iterator& e)
{
std::cout << e.what() << '\n';
}
} }
<a target="_blank" href="http://melpon.org/wandbox/permlink/nKF1QcieoCHm6Lez"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/oUU2X0pbZq7gawRB"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
["bravo","charly"] ["bravo","charly"]
42 42
{"one":"eins"} {"one":"eins"}
[json.exception.invalid_iterator.204] iterators out of range
...@@ -19,7 +19,7 @@ int main() ...@@ -19,7 +19,7 @@ int main()
{ {
auto r3 = value.get_ref<json::number_float_t&>(); auto r3 = value.get_ref<json::number_float_t&>();
} }
catch (std::domain_error& ex) catch (json::type_error& ex)
{ {
std::cout << ex.what() << '\n'; std::cout << ex.what() << '\n';
} }
......
<a target="_blank" href="http://melpon.org/wandbox/permlink/WiO1oBWDvIs82OX1"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/lsl8Ex3d3SOYnKHu"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
17 17 17 17
incompatible ReferenceType for get_ref, actual type is number [json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number
17 17
[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number
...@@ -19,9 +19,9 @@ int main() ...@@ -19,9 +19,9 @@ int main()
{ {
json::json_pointer p9("foo"); json::json_pointer p9("foo");
} }
catch (std::domain_error& e) catch (json::parse_error& e)
{ {
std::cout << "domain_error: " << e.what() << '\n'; std::cout << e.what() << '\n';
} }
// error: JSON pointer uses escape symbol ~ not followed by 0 or 1 // error: JSON pointer uses escape symbol ~ not followed by 0 or 1
...@@ -29,9 +29,9 @@ int main() ...@@ -29,9 +29,9 @@ int main()
{ {
json::json_pointer p10("/foo/~"); json::json_pointer p10("/foo/~");
} }
catch (std::domain_error& e) catch (json::parse_error& e)
{ {
std::cout << "domain_error: " << e.what() << '\n'; std::cout << e.what() << '\n';
} }
// error: JSON pointer uses escape symbol ~ not followed by 0 or 1 // error: JSON pointer uses escape symbol ~ not followed by 0 or 1
...@@ -39,8 +39,8 @@ int main() ...@@ -39,8 +39,8 @@ int main()
{ {
json::json_pointer p11("/foo/~3"); json::json_pointer p11("/foo/~3");
} }
catch (std::domain_error& e) catch (json::parse_error& e)
{ {
std::cout << "domain_error: " << e.what() << '\n'; std::cout << e.what() << '\n';
} }
} }
<a target="_blank" href="http://melpon.org/wandbox/permlink/WM2WWKnXdmdw17Wu"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/Wlvqfd3JpEXTv2iH"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
domain_error: JSON pointer must be empty or begin with '/' [json.exception.parse_error.107] parse error at 1: JSON pointer must be empty or begin with '/' - was: 'foo'
domain_error: escape error: '~' must be followed with '0' or '1' [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
domain_error: escape error: '~' must be followed with '0' or '1' [json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
[json.exception.parse_error.107] parse error at 1: JSON pointer must be empty or begin with '/' - was: 'foo'
[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
[json.exception.parse_error.108] parse error: escape character '~' must be followed with '0' or '1'
...@@ -8,10 +8,20 @@ int main() ...@@ -8,10 +8,20 @@ int main()
json j_no_init_list = json::object(); json j_no_init_list = json::object();
json j_empty_init_list = json::object({}); json j_empty_init_list = json::object({});
json j_list_of_pairs = json::object({ {"one", 1}, {"two", 2} }); json j_list_of_pairs = json::object({ {"one", 1}, {"two", 2} });
//json j_invalid_list = json::object({ "one", 1 }); // would throw
// serialize the JSON objects // serialize the JSON objects
std::cout << j_no_init_list << '\n'; std::cout << j_no_init_list << '\n';
std::cout << j_empty_init_list << '\n'; std::cout << j_empty_init_list << '\n';
std::cout << j_list_of_pairs << '\n'; std::cout << j_list_of_pairs << '\n';
// example for an exception
try
{
// can only create an object from a list of pairs
json j_invalid_object = json::object({{ "one", 1, 2 }});
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
} }
<a target="_blank" href="http://melpon.org/wandbox/permlink/hhxRaUctq3FA54SW"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/Ub9U5AMbng3oZiao"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
{} {}
{} {}
{"one":1,"two":2} {"one":1,"two":2}
[json.exception.type_error.301] cannot create object from initializer list
...@@ -46,4 +46,14 @@ int main() ...@@ -46,4 +46,14 @@ int main()
{ {
std::cout << i.first << ": " << i.second << '\n'; std::cout << i.first << ": " << i.second << '\n';
} }
// example for an exception
try
{
bool v1 = json_types["string"];
}
catch (json::type_error& e)
{
std::cout << e.what() << '\n';
}
} }
<a target="_blank" href="http://melpon.org/wandbox/permlink/rUGX6AaVuZfwiiYI"><b>online</b></a> <a target="_blank" href="http://melpon.org/wandbox/permlink/drFSKFXJd8IMzMK3"><b>online</b></a>
\ No newline at end of file \ No newline at end of file
...@@ -9,3 +9,4 @@ number: {"floating-point":17.23,"integer":42} ...@@ -9,3 +9,4 @@ number: {"floating-point":17.23,"integer":42}
null: null null: null
boolean: true boolean: true
array: [1,2,3,4,5] array: [1,2,3,4,5]
[json.exception.type_error.302] type must be boolean, but is string
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -41,26 +41,22 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ...@@ -41,26 +41,22 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
// parse serialization // parse serialization
json j2 = json::from_cbor(vec2); json j2 = json::from_cbor(vec2);
// deserializations must match // serializations must match
assert(j1 == j2); assert(json::to_cbor(j2) == vec2);
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parsing a CBOR serialization must not fail // parsing a CBOR serialization must not fail
assert(false); assert(false);
} }
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parse errors are ok, because input may be random bytes // parse errors are ok, because input may be random bytes
} }
catch (const std::out_of_range&) catch (const json::type_error&)
{ {
// parse errors are ok, because input may be random bytes // type errors can occur during parsing, too
}
catch (const std::domain_error&)
{
// parse errors are ok, because input may be random bytes
} }
// return 0 - non-zero return values are reserved for future use // return 0 - non-zero return values are reserved for future use
......
...@@ -49,13 +49,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ...@@ -49,13 +49,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
// serializations must match // serializations must match
assert(s1 == s2); assert(s1 == s2);
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parsing a JSON serialization must not fail // parsing a JSON serialization must not fail
assert(false); assert(false);
} }
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parse errors are ok, because input may be random bytes // parse errors are ok, because input may be random bytes
} }
......
...@@ -44,23 +44,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ...@@ -44,23 +44,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
// deserializations must match // deserializations must match
assert(j1 == j2); assert(j1 == j2);
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parsing a MessagePack serialization must not fail // parsing a MessagePack serialization must not fail
assert(false); assert(false);
} }
} }
catch (const std::invalid_argument&) catch (const json::parse_error&)
{ {
// parse errors are ok, because input may be random bytes // parse errors are ok, because input may be random bytes
} }
catch (const std::out_of_range&) catch (const json::type_error&)
{ {
// parse errors are ok, because input may be random bytes // type errors can occur during parsing, too
}
catch (const std::domain_error&)
{
// parse errors are ok, because input may be random bytes
} }
// return 0 - non-zero return values are reserved for future use // return 0 - non-zero return values are reserved for future use
......
...@@ -240,8 +240,9 @@ TEST_CASE("algorithms") ...@@ -240,8 +240,9 @@ TEST_CASE("algorithms")
SECTION("sorting an object") SECTION("sorting an object")
{ {
json j({{"one", 1}, {"two", 2}}); json j({{"one", 1}, {"two", 2}});
CHECK_THROWS_AS(std::sort(j.begin(), j.end()), std::domain_error); CHECK_THROWS_AS(std::sort(j.begin(), j.end()), json::invalid_iterator);
CHECK_THROWS_WITH(std::sort(j.begin(), j.end()), "cannot use offsets with object iterators"); CHECK_THROWS_WITH(std::sort(j.begin(), j.end()),
"[json.exception.invalid_iterator.209] cannot use offsets with object iterators");
} }
} }
......
This diff is collapsed.
...@@ -147,8 +147,8 @@ TEST_CASE("const_iterator class") ...@@ -147,8 +147,8 @@ TEST_CASE("const_iterator class")
{ {
json j(json::value_t::null); json j(json::value_t::null);
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK_THROWS_AS(*it, std::out_of_range); CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "cannot get value"); CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("number") SECTION("number")
...@@ -157,8 +157,8 @@ TEST_CASE("const_iterator class") ...@@ -157,8 +157,8 @@ TEST_CASE("const_iterator class")
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK(*it == json(17)); CHECK(*it == json(17));
it = j.cend(); it = j.cend();
CHECK_THROWS_AS(*it, std::out_of_range); CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "cannot get value"); CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("object") SECTION("object")
...@@ -182,8 +182,8 @@ TEST_CASE("const_iterator class") ...@@ -182,8 +182,8 @@ TEST_CASE("const_iterator class")
{ {
json j(json::value_t::null); json j(json::value_t::null);
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK_THROWS_AS(it->type_name(), std::out_of_range); CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "cannot get value"); CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("number") SECTION("number")
...@@ -192,8 +192,8 @@ TEST_CASE("const_iterator class") ...@@ -192,8 +192,8 @@ TEST_CASE("const_iterator class")
json::const_iterator it = j.cbegin(); json::const_iterator it = j.cbegin();
CHECK(it->type_name() == "number"); CHECK(it->type_name() == "number");
it = j.cend(); it = j.cend();
CHECK_THROWS_AS(it->type_name(), std::out_of_range); CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "cannot get value"); CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("object") SECTION("object")
......
...@@ -131,8 +131,8 @@ TEST_CASE("iterator class") ...@@ -131,8 +131,8 @@ TEST_CASE("iterator class")
{ {
json j(json::value_t::null); json j(json::value_t::null);
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK_THROWS_AS(*it, std::out_of_range); CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "cannot get value"); CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("number") SECTION("number")
...@@ -141,8 +141,8 @@ TEST_CASE("iterator class") ...@@ -141,8 +141,8 @@ TEST_CASE("iterator class")
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK(*it == json(17)); CHECK(*it == json(17));
it = j.end(); it = j.end();
CHECK_THROWS_AS(*it, std::out_of_range); CHECK_THROWS_AS(*it, json::invalid_iterator);
CHECK_THROWS_WITH(*it, "cannot get value"); CHECK_THROWS_WITH(*it, "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("object") SECTION("object")
...@@ -166,8 +166,8 @@ TEST_CASE("iterator class") ...@@ -166,8 +166,8 @@ TEST_CASE("iterator class")
{ {
json j(json::value_t::null); json j(json::value_t::null);
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK_THROWS_AS(it->type_name(), std::out_of_range); CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "cannot get value"); CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("number") SECTION("number")
...@@ -176,8 +176,8 @@ TEST_CASE("iterator class") ...@@ -176,8 +176,8 @@ TEST_CASE("iterator class")
json::iterator it = j.begin(); json::iterator it = j.begin();
CHECK(it->type_name() == "number"); CHECK(it->type_name() == "number");
it = j.end(); it = j.end();
CHECK_THROWS_AS(it->type_name(), std::out_of_range); CHECK_THROWS_AS(it->type_name(), json::invalid_iterator);
CHECK_THROWS_WITH(it->type_name(), "cannot get value"); CHECK_THROWS_WITH(it->type_name(), "[json.exception.invalid_iterator.214] cannot get value");
} }
SECTION("object") SECTION("object")
......
...@@ -190,8 +190,10 @@ TEST_CASE("lexer class") ...@@ -190,8 +190,10 @@ TEST_CASE("lexer class")
SECTION("to_unicode") SECTION("to_unicode")
{ {
CHECK(json::lexer::to_unicode(0x1F4A9) == "💩"); // lexer to call to_unicode on
CHECK_THROWS_AS(json::lexer::to_unicode(0x200000), std::out_of_range); json::lexer dummy_lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(""), 0);
CHECK_THROWS_WITH(json::lexer::to_unicode(0x200000), "code points above 0x10FFFF are invalid"); CHECK(dummy_lexer.to_unicode(0x1F4A9) == "💩");
CHECK_THROWS_AS(dummy_lexer.to_unicode(0x200000), json::parse_error);
CHECK_THROWS_WITH(dummy_lexer.to_unicode(0x200000), "[json.exception.parse_error.103] parse error: code points above 0x10FFFF are invalid");
} }
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -90,15 +90,17 @@ TEST_CASE("deserialization") ...@@ -90,15 +90,17 @@ TEST_CASE("deserialization")
std::stringstream ss1, ss2; std::stringstream ss1, ss2;
ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
CHECK_THROWS_AS(json::parse(ss1), std::invalid_argument); CHECK_THROWS_AS(json::parse(ss1), json::parse_error);
CHECK_THROWS_WITH(json::parse(ss2), "parse error - unexpected end of input; expected ']'"); CHECK_THROWS_WITH(json::parse(ss2),
"[json.exception.parse_error.101] parse error at 30: parse error - unexpected end of input; expected ']'");
} }
SECTION("string") SECTION("string")
{ {
json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}"; json::string_t s = "[\"foo\",1,2,3,false,{\"one\":1}";
CHECK_THROWS_AS(json::parse(s), std::invalid_argument); CHECK_THROWS_AS(json::parse(s), json::parse_error);
CHECK_THROWS_WITH(json::parse(s), "parse error - unexpected end of input; expected ']'"); CHECK_THROWS_WITH(json::parse(s),
"[json.exception.parse_error.101] parse error at 29: parse error - unexpected end of input; expected ']'");
} }
SECTION("operator<<") SECTION("operator<<")
...@@ -107,8 +109,9 @@ TEST_CASE("deserialization") ...@@ -107,8 +109,9 @@ TEST_CASE("deserialization")
ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
json j; json j;
CHECK_THROWS_AS(j << ss1, std::invalid_argument); CHECK_THROWS_AS(j << ss1, json::parse_error);
CHECK_THROWS_WITH(j << ss2, "parse error - unexpected end of input; expected ']'"); CHECK_THROWS_WITH(j << ss2,
"[json.exception.parse_error.101] parse error at 30: parse error - unexpected end of input; expected ']'");
} }
SECTION("operator>>") SECTION("operator>>")
...@@ -117,15 +120,16 @@ TEST_CASE("deserialization") ...@@ -117,15 +120,16 @@ TEST_CASE("deserialization")
ss1 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
ss2 << "[\"foo\",1,2,3,false,{\"one\":1}"; ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
json j; json j;
CHECK_THROWS_AS(ss1 >> j, std::invalid_argument); CHECK_THROWS_AS(ss1 >> j, json::parse_error);
CHECK_THROWS_WITH(ss2 >> j, "parse error - unexpected end of input; expected ']'"); CHECK_THROWS_WITH(ss2 >> j,
"[json.exception.parse_error.101] parse error at 30: parse error - unexpected end of input; expected ']'");
} }
SECTION("user-defined string literal") SECTION("user-defined string literal")
{ {
CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, std::invalid_argument); CHECK_THROWS_AS("[\"foo\",1,2,3,false,{\"one\":1}"_json, json::parse_error);
CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json, CHECK_THROWS_WITH("[\"foo\",1,2,3,false,{\"one\":1}"_json,
"parse error - unexpected end of input; expected ']'"); "[json.exception.parse_error.101] parse error at 29: parse error - unexpected end of input; expected ']'");
} }
} }
...@@ -178,7 +182,7 @@ TEST_CASE("deserialization") ...@@ -178,7 +182,7 @@ TEST_CASE("deserialization")
SECTION("empty container") SECTION("empty container")
{ {
std::vector<uint8_t> v; std::vector<uint8_t> v;
CHECK_THROWS_AS(json::parse(v), std::invalid_argument); CHECK_THROWS_AS(json::parse(v), json::parse_error);
} }
} }
...@@ -223,7 +227,7 @@ TEST_CASE("deserialization") ...@@ -223,7 +227,7 @@ TEST_CASE("deserialization")
SECTION("with empty range") SECTION("with empty range")
{ {
std::vector<uint8_t> v; std::vector<uint8_t> v;
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
} }
...@@ -233,91 +237,91 @@ TEST_CASE("deserialization") ...@@ -233,91 +237,91 @@ TEST_CASE("deserialization")
SECTION("case 1") SECTION("case 1")
{ {
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'}; uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 2") SECTION("case 2")
{ {
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'}; uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 3") SECTION("case 3")
{ {
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'}; uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 4") SECTION("case 4")
{ {
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'}; uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 5") SECTION("case 5")
{ {
uint8_t v[] = {'\"', 0x7F, 0xC1}; uint8_t v[] = {'\"', 0x7F, 0xC1};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 6") SECTION("case 6")
{ {
uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F}; uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 7") SECTION("case 7")
{ {
uint8_t v[] = {'\"', 0x7F, 0xDF, 0xC0}; uint8_t v[] = {'\"', 0x7F, 0xDF, 0xC0};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 8") SECTION("case 8")
{ {
uint8_t v[] = {'\"', 0x7F, 0xE0, 0x9F}; uint8_t v[] = {'\"', 0x7F, 0xE0, 0x9F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 9") SECTION("case 9")
{ {
uint8_t v[] = {'\"', 0x7F, 0xEF, 0xC0}; uint8_t v[] = {'\"', 0x7F, 0xEF, 0xC0};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 10") SECTION("case 10")
{ {
uint8_t v[] = {'\"', 0x7F, 0xED, 0x7F}; uint8_t v[] = {'\"', 0x7F, 0xED, 0x7F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 11") SECTION("case 11")
{ {
uint8_t v[] = {'\"', 0x7F, 0xF0, 0x8F}; uint8_t v[] = {'\"', 0x7F, 0xF0, 0x8F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 12") SECTION("case 12")
{ {
uint8_t v[] = {'\"', 0x7F, 0xF0, 0xC0}; uint8_t v[] = {'\"', 0x7F, 0xF0, 0xC0};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 13") SECTION("case 13")
{ {
uint8_t v[] = {'\"', 0x7F, 0xF3, 0x7F}; uint8_t v[] = {'\"', 0x7F, 0xF3, 0x7F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 14") SECTION("case 14")
{ {
uint8_t v[] = {'\"', 0x7F, 0xF3, 0xC0}; uint8_t v[] = {'\"', 0x7F, 0xF3, 0xC0};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
SECTION("case 15") SECTION("case 15")
{ {
uint8_t v[] = {'\"', 0x7F, 0xF4, 0x7F}; uint8_t v[] = {'\"', 0x7F, 0xF4, 0x7F};
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), std::invalid_argument); CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error);
} }
} }
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -1016,6 +1016,90 @@ TEST_CASE("MessagePack") ...@@ -1016,6 +1016,90 @@ TEST_CASE("MessagePack")
json j = json::from_msgpack(given); json j = json::from_msgpack(given);
CHECK(j.get<double>() == Approx(25.0000019073486)); CHECK(j.get<double>() == Approx(25.0000019073486));
} }
SECTION("errors")
{
SECTION("too short byte vector")
{
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcc})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcd})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xce})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcc})),
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd})),
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
}
SECTION("unsupported bytes")
{
SECTION("concrete examples")
{
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc1})), json::parse_error);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc1})),
"[json.exception.parse_error.112] parse error at 1: error reading MessagePack; last byte: 0xc1");
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc6})), json::parse_error);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc6})),
"[json.exception.parse_error.112] parse error at 1: error reading MessagePack; last byte: 0xc6");
}
SECTION("all unsupported bytes")
{
for (auto byte :
{
// never used
0xc1,
// bin
0xc4, 0xc5, 0xc6,
// ext
0xc7, 0xc8, 0xc9,
// fixext
0xd4, 0xd5, 0xd6, 0xd7, 0xd8
})
{
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({static_cast<uint8_t>(byte)})), json::parse_error);
}
}
}
}
} }
...@@ -1116,7 +1200,7 @@ TEST_CASE("MessagePack roundtrips", "[hide]") ...@@ -1116,7 +1200,7 @@ TEST_CASE("MessagePack roundtrips", "[hide]")
"test/data/nst_json_testsuite/test_parsing/y_number_after_space.json", "test/data/nst_json_testsuite/test_parsing/y_number_after_space.json",
"test/data/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json", "test/data/nst_json_testsuite/test_parsing/y_number_double_close_to_zero.json",
"test/data/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json", "test/data/nst_json_testsuite/test_parsing/y_number_double_huge_neg_exp.json",
"test/data/nst_json_testsuite/test_parsing/y_number_huge_exp.json", //"test/data/nst_json_testsuite/test_parsing/y_number_huge_exp.json",
"test/data/nst_json_testsuite/test_parsing/y_number_int_with_exp.json", "test/data/nst_json_testsuite/test_parsing/y_number_int_with_exp.json",
"test/data/nst_json_testsuite/test_parsing/y_number_minus_zero.json", "test/data/nst_json_testsuite/test_parsing/y_number_minus_zero.json",
"test/data/nst_json_testsuite/test_parsing/y_number_negative_int.json", "test/data/nst_json_testsuite/test_parsing/y_number_negative_int.json",
...@@ -1128,9 +1212,9 @@ TEST_CASE("MessagePack roundtrips", "[hide]") ...@@ -1128,9 +1212,9 @@ TEST_CASE("MessagePack roundtrips", "[hide]")
"test/data/nst_json_testsuite/test_parsing/y_number_real_exponent.json", "test/data/nst_json_testsuite/test_parsing/y_number_real_exponent.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json", "test/data/nst_json_testsuite/test_parsing/y_number_real_fraction_exponent.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json", "test/data/nst_json_testsuite/test_parsing/y_number_real_neg_exp.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json", //"test/data/nst_json_testsuite/test_parsing/y_number_real_neg_overflow.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json", "test/data/nst_json_testsuite/test_parsing/y_number_real_pos_exponent.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json", //"test/data/nst_json_testsuite/test_parsing/y_number_real_pos_overflow.json",
"test/data/nst_json_testsuite/test_parsing/y_number_real_underflow.json", "test/data/nst_json_testsuite/test_parsing/y_number_real_underflow.json",
"test/data/nst_json_testsuite/test_parsing/y_number_simple_int.json", "test/data/nst_json_testsuite/test_parsing/y_number_simple_int.json",
"test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json", "test/data/nst_json_testsuite/test_parsing/y_number_simple_real.json",
......
This diff is collapsed.
This diff is collapsed.
...@@ -38,6 +38,9 @@ TEST_CASE("Unicode", "[hide]") ...@@ -38,6 +38,9 @@ TEST_CASE("Unicode", "[hide]")
{ {
SECTION("full enumeration of Unicode code points") SECTION("full enumeration of Unicode code points")
{ {
// lexer to call to_unicode on
json::lexer dummy_lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(""), 0);
// create an escaped string from a code point // create an escaped string from a code point
const auto codepoint_to_unicode = [](std::size_t cp) const auto codepoint_to_unicode = [](std::size_t cp)
{ {
...@@ -85,7 +88,7 @@ TEST_CASE("Unicode", "[hide]") ...@@ -85,7 +88,7 @@ TEST_CASE("Unicode", "[hide]")
// they are checked with codepoint_to_unicode. // they are checked with codepoint_to_unicode.
if (cp > 0x1f and cp != 0x22 and cp != 0x5c) if (cp > 0x1f and cp != 0x22 and cp != 0x5c)
{ {
unescaped_string = json::lexer::to_unicode(cp); unescaped_string = dummy_lexer.to_unicode(cp);
} }
} }
else else
...@@ -97,7 +100,7 @@ TEST_CASE("Unicode", "[hide]") ...@@ -97,7 +100,7 @@ TEST_CASE("Unicode", "[hide]")
const auto codepoint2 = 0xdc00u + ((cp - 0x10000u) & 0x3ffu); const auto codepoint2 = 0xdc00u + ((cp - 0x10000u) & 0x3ffu);
escaped_string = codepoint_to_unicode(codepoint1); escaped_string = codepoint_to_unicode(codepoint1);
escaped_string += codepoint_to_unicode(codepoint2); escaped_string += codepoint_to_unicode(codepoint2);
unescaped_string += json::lexer::to_unicode(codepoint1, codepoint2); unescaped_string += dummy_lexer.to_unicode(codepoint1, codepoint2);
} }
// all other code points are valid and must not yield parse errors // all other code points are valid and must not yield parse errors
...@@ -170,7 +173,7 @@ TEST_CASE("Unicode", "[hide]") ...@@ -170,7 +173,7 @@ TEST_CASE("Unicode", "[hide]")
SECTION("error for incomplete/wrong BOM") SECTION("error for incomplete/wrong BOM")
{ {
CHECK_THROWS_AS(json::parse("\xef\xbb"), std::invalid_argument); CHECK_THROWS_AS(json::parse("\xef\xbb"), json::parse_error);
CHECK_THROWS_AS(json::parse("\xef\xbb\xbb"), std::invalid_argument); CHECK_THROWS_AS(json::parse("\xef\xbb\xbb"), json::parse_error);
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment