/src/glaze/fuzzing/json_jmespath.cpp
Line | Count | Source |
1 | | #include <algorithm> |
2 | | #include <cstddef> |
3 | | #include <cstdint> |
4 | | #include <glaze/glaze.hpp> |
5 | | #include <glaze/json/jmespath.hpp> |
6 | | #include <string> |
7 | | #include <string_view> |
8 | | |
9 | | struct Person |
10 | | { |
11 | | std::string first_name{}; |
12 | | std::string last_name{}; |
13 | | uint16_t age{}; |
14 | | }; |
15 | | |
16 | | namespace |
17 | | { |
18 | | template <bool null_terminated> |
19 | | void impl(const std::size_t pathsize, std::string_view all_buffer) |
20 | 10.1k | { |
21 | | // make separate allocations to make it easier for address sanitizer to catch |
22 | | // out of bounds access. also, make the size known up front so the allocation is |
23 | | // as tight as possible. |
24 | 10.1k | std::vector<char> path(pathsize + +null_terminated); |
25 | 10.1k | std::copy(all_buffer.begin(), all_buffer.begin() + pathsize, path.begin()); |
26 | | |
27 | 10.1k | std::vector<char> buffer(all_buffer.size() - pathsize + +null_terminated); |
28 | 10.1k | std::copy(all_buffer.begin() + pathsize, all_buffer.end(), buffer.begin()); |
29 | | |
30 | 10.1k | Person child{}; |
31 | 10.1k | static constexpr glz::opts options{.null_terminated = null_terminated}; |
32 | 10.1k | [[maybe_unused]] auto result = |
33 | 10.1k | glz::read_jmespath<options>(std::string_view(path.data(), path.size() - +null_terminated), child, |
34 | 10.1k | std::string_view(buffer.data(), buffer.size() - +null_terminated)); |
35 | 10.1k | } json_jmespath.cpp:void (anonymous namespace)::impl<true>(unsigned long, std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line | Count | Source | 20 | 5.65k | { | 21 | | // make separate allocations to make it easier for address sanitizer to catch | 22 | | // out of bounds access. also, make the size known up front so the allocation is | 23 | | // as tight as possible. | 24 | 5.65k | std::vector<char> path(pathsize + +null_terminated); | 25 | 5.65k | std::copy(all_buffer.begin(), all_buffer.begin() + pathsize, path.begin()); | 26 | | | 27 | 5.65k | std::vector<char> buffer(all_buffer.size() - pathsize + +null_terminated); | 28 | 5.65k | std::copy(all_buffer.begin() + pathsize, all_buffer.end(), buffer.begin()); | 29 | | | 30 | 5.65k | Person child{}; | 31 | 5.65k | static constexpr glz::opts options{.null_terminated = null_terminated}; | 32 | 5.65k | [[maybe_unused]] auto result = | 33 | 5.65k | glz::read_jmespath<options>(std::string_view(path.data(), path.size() - +null_terminated), child, | 34 | 5.65k | std::string_view(buffer.data(), buffer.size() - +null_terminated)); | 35 | 5.65k | } |
json_jmespath.cpp:void (anonymous namespace)::impl<false>(unsigned long, std::__1::basic_string_view<char, std::__1::char_traits<char> >) Line | Count | Source | 20 | 4.49k | { | 21 | | // make separate allocations to make it easier for address sanitizer to catch | 22 | | // out of bounds access. also, make the size known up front so the allocation is | 23 | | // as tight as possible. | 24 | 4.49k | std::vector<char> path(pathsize + +null_terminated); | 25 | 4.49k | std::copy(all_buffer.begin(), all_buffer.begin() + pathsize, path.begin()); | 26 | | | 27 | 4.49k | std::vector<char> buffer(all_buffer.size() - pathsize + +null_terminated); | 28 | 4.49k | std::copy(all_buffer.begin() + pathsize, all_buffer.end(), buffer.begin()); | 29 | | | 30 | 4.49k | Person child{}; | 31 | 4.49k | static constexpr glz::opts options{.null_terminated = null_terminated}; | 32 | 4.49k | [[maybe_unused]] auto result = | 33 | 4.49k | glz::read_jmespath<options>(std::string_view(path.data(), path.size() - +null_terminated), child, | 34 | 4.49k | std::string_view(buffer.data(), buffer.size() - +null_terminated)); | 35 | 4.49k | } |
|
36 | | } |
37 | | |
38 | | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) |
39 | 10.1k | { |
40 | 10.1k | constexpr auto bytes_used_for_nullterm = 1; |
41 | 10.1k | constexpr auto bytes_used_for_size = 2; |
42 | 10.1k | if (Size < bytes_used_for_size + bytes_used_for_nullterm) return 0; |
43 | | |
44 | 10.1k | const bool null_terminated = Data[0]; |
45 | 10.1k | Data += bytes_used_for_nullterm; |
46 | 10.1k | Size -= bytes_used_for_nullterm; |
47 | | |
48 | 10.1k | const auto pathsize = std::min(Size - bytes_used_for_size, size_t{Data[0]} + (Data[1] << 8)); |
49 | 10.1k | Data += bytes_used_for_size; |
50 | 10.1k | Size -= bytes_used_for_size; |
51 | | |
52 | 10.1k | const std::string_view all_buffer{(const char*)Data, Size}; |
53 | | |
54 | 10.1k | if (null_terminated) { |
55 | 5.65k | impl<true>(pathsize, all_buffer); |
56 | 5.65k | } |
57 | 4.49k | else { |
58 | 4.49k | impl<false>(pathsize, all_buffer); |
59 | 4.49k | } |
60 | | |
61 | 10.1k | return 0; |
62 | 10.1k | } |