🔨 a lot of restructuring
- removed uncached input stream adapter; it was too slow anyway - implemented a class binary_read which parses CBOR based on input adapters - in the CBOR parser, numbers are created via memcpy to avoid undefined behavior
This commit is contained in:
parent
3a5cf9bd0a
commit
89efe627fe
4 changed files with 948 additions and 423 deletions
6
Makefile
6
Makefile
|
@ -47,7 +47,8 @@ doctest:
|
||||||
# -Wno-keyword-macro: unit-tests use "#define private public"
|
# -Wno-keyword-macro: unit-tests use "#define private public"
|
||||||
# -Wno-deprecated-declarations: the library deprecated some functions
|
# -Wno-deprecated-declarations: the library deprecated some functions
|
||||||
# -Wno-weak-vtables: exception class is defined inline, but has virtual method
|
# -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 "for(const auto i...)"
|
||||||
|
# -Wno-float-equal: not all comparisons in the tests can be replaced by Approx
|
||||||
pedantic_clang:
|
pedantic_clang:
|
||||||
$(MAKE) json_unit CXXFLAGS="\
|
$(MAKE) json_unit CXXFLAGS="\
|
||||||
-std=c++11 \
|
-std=c++11 \
|
||||||
|
@ -58,7 +59,8 @@ pedantic_clang:
|
||||||
-Wno-keyword-macro \
|
-Wno-keyword-macro \
|
||||||
-Wno-deprecated-declarations \
|
-Wno-deprecated-declarations \
|
||||||
-Wno-weak-vtables \
|
-Wno-weak-vtables \
|
||||||
-Wno-range-loop-analysis"
|
-Wno-range-loop-analysis \
|
||||||
|
-Wno-float-equal"
|
||||||
|
|
||||||
# calling GCC with most warnings
|
# calling GCC with most warnings
|
||||||
pedantic_gcc:
|
pedantic_gcc:
|
||||||
|
|
1049
src/json.hpp
1049
src/json.hpp
File diff suppressed because it is too large
Load diff
|
@ -1166,35 +1166,35 @@ TEST_CASE("CBOR")
|
||||||
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), json::parse_error);
|
||||||
|
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x18})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x18})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 2: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 2: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 3: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 2: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 3: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 4: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 5: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 2: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 3: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 4: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 5: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 6: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 7: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 8: unexpected end of input");
|
||||||
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
|
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 9: unexpected end of input");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("unsupported bytes")
|
SECTION("unsupported bytes")
|
||||||
|
@ -1756,7 +1756,7 @@ TEST_CASE("examples from RFC 7049 Appendix A")
|
||||||
CHECK(json::parse("\"\\ud800\\udd51\"") == json::from_cbor(std::vector<uint8_t>({0x64, 0xf0, 0x90, 0x85, 0x91})));
|
CHECK(json::parse("\"\\ud800\\udd51\"") == json::from_cbor(std::vector<uint8_t>({0x64, 0xf0, 0x90, 0x85, 0x91})));
|
||||||
|
|
||||||
// indefinite length strings
|
// indefinite length strings
|
||||||
CHECK(json::parse("\"streaming\"") == json::from_cbor(std::vector<uint8_t>({0x7f, 0x65, 0x73, 0x74, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x67, 0xff})));
|
CHECK(json::parse("\"streaming\"") == json::from_cbor(std::vector<uint8_t>({0x7f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0xff})));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("arrays")
|
SECTION("arrays")
|
||||||
|
|
|
@ -629,7 +629,7 @@ TEST_CASE("regression tests")
|
||||||
std::vector<uint8_t> vec {0x65, 0xf5, 0x0a, 0x48, 0x21};
|
std::vector<uint8_t> vec {0x65, 0xf5, 0x0a, 0x48, 0x21};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec),
|
CHECK_THROWS_WITH(json::from_cbor(vec),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 5 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 6: unexpected end of input");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)")
|
SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)")
|
||||||
|
@ -650,19 +650,19 @@ TEST_CASE("regression tests")
|
||||||
std::vector<uint8_t> vec3 {0xf9, 0x8f};
|
std::vector<uint8_t> vec3 {0xf9, 0x8f};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec3),
|
CHECK_THROWS_WITH(json::from_cbor(vec3),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 3: unexpected end of input");
|
||||||
|
|
||||||
// related test case: incomplete Single-Precision Float (CBOR)
|
// related test case: incomplete Single-Precision Float (CBOR)
|
||||||
std::vector<uint8_t> vec4 {0xfa, 0x8f, 0x0a};
|
std::vector<uint8_t> vec4 {0xfa, 0x8f, 0x0a};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec4), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec4), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec4),
|
CHECK_THROWS_WITH(json::from_cbor(vec4),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 4: unexpected end of input");
|
||||||
|
|
||||||
// related test case: incomplete Double-Precision Float (CBOR)
|
// related test case: incomplete Double-Precision Float (CBOR)
|
||||||
std::vector<uint8_t> vec5 {0xfb, 0x8f, 0x0a};
|
std::vector<uint8_t> vec5 {0xfb, 0x8f, 0x0a};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec5), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec5), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec5),
|
CHECK_THROWS_WITH(json::from_cbor(vec5),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 4: unexpected end of input");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)")
|
SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)")
|
||||||
|
@ -705,7 +705,7 @@ TEST_CASE("regression tests")
|
||||||
std::vector<uint8_t> vec2;
|
std::vector<uint8_t> vec2;
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
||||||
"[json.exception.parse_error.110] parse error at 1: cannot read 1 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 1: unexpected end of input");
|
||||||
CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error);
|
CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_msgpack(vec2),
|
CHECK_THROWS_WITH(json::from_msgpack(vec2),
|
||||||
"[json.exception.parse_error.110] parse error at 1: cannot read 1 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 1: cannot read 1 bytes from vector");
|
||||||
|
@ -717,19 +717,19 @@ TEST_CASE("regression tests")
|
||||||
std::vector<uint8_t> vec1 {0x7f};
|
std::vector<uint8_t> vec1 {0x7f};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec1),
|
CHECK_THROWS_WITH(json::from_cbor(vec1),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 2: unexpected end of input");
|
||||||
|
|
||||||
// related test case: empty array (indefinite length)
|
// related test case: empty array (indefinite length)
|
||||||
std::vector<uint8_t> vec2 {0x9f};
|
std::vector<uint8_t> vec2 {0x9f};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 2: unexpected end of input");
|
||||||
|
|
||||||
// related test case: empty map (indefinite length)
|
// related test case: empty map (indefinite length)
|
||||||
std::vector<uint8_t> vec3 {0xbf};
|
std::vector<uint8_t> vec3 {0xbf};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec3),
|
CHECK_THROWS_WITH(json::from_cbor(vec3),
|
||||||
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 2: unexpected end of input");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
|
SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
|
||||||
|
@ -763,19 +763,19 @@ TEST_CASE("regression tests")
|
||||||
std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
|
std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec1),
|
CHECK_THROWS_WITH(json::from_cbor(vec1),
|
||||||
"[json.exception.parse_error.110] parse error at 4: cannot read 1 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 4: unexpected end of input");
|
||||||
|
|
||||||
// related test case: nonempty array (indefinite length)
|
// related test case: nonempty array (indefinite length)
|
||||||
std::vector<uint8_t> vec2 {0x9f, 0x01};
|
std::vector<uint8_t> vec2 {0x9f, 0x01};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
||||||
"[json.exception.parse_error.110] parse error at 3: cannot read 1 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 3: unexpected end of input");
|
||||||
|
|
||||||
// related test case: nonempty map (indefinite length)
|
// related test case: nonempty map (indefinite length)
|
||||||
std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};
|
std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};
|
||||||
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
|
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
|
||||||
CHECK_THROWS_WITH(json::from_cbor(vec3),
|
CHECK_THROWS_WITH(json::from_cbor(vec3),
|
||||||
"[json.exception.parse_error.110] parse error at 5: cannot read 1 bytes from vector");
|
"[json.exception.parse_error.110] parse error at 5: unexpected end of input");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("issue #414 - compare with literal 0)")
|
SECTION("issue #414 - compare with literal 0)")
|
||||||
|
|
Loading…
Reference in a new issue