• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <grpc/slice.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 
20 #include <algorithm>
21 #include <cstdint>
22 #include <string>
23 #include <vector>
24 
25 #include "absl/strings/str_cat.h"
26 #include "absl/strings/str_join.h"
27 #include "absl/types/optional.h"
28 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
29 #include "src/core/ext/transport/chttp2/transport/decode_huff.h"
30 
31 bool squelch = true;
32 bool leak_check = true;
33 
ToString(absl::optional<std::vector<uint8_t>> s)34 std::string ToString(absl::optional<std::vector<uint8_t>> s) {
35   if (s == absl::nullopt) return "nullopt";
36   return absl::StrCat("{", absl::StrJoin(*s, ","), "}");
37 }
38 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)39 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
40   grpc_slice uncompressed =
41       grpc_slice_from_copied_buffer(reinterpret_cast<const char*>(data), size);
42   grpc_slice compressed = grpc_chttp2_huffman_compress(uncompressed);
43   std::vector<uint8_t> uncompressed_again;
44   auto add = [&uncompressed_again](uint8_t c) {
45     uncompressed_again.push_back(c);
46   };
47   auto fail = [&](const char* reason) {
48     fprintf(stderr,
49             "Failed: %s\nuncompressed: %s\ncompressed: %s\nuncompressed_again: "
50             "%s\n",
51             reason, ToString(std::vector<uint8_t>(data, data + size)).c_str(),
52             ToString(std::vector<uint8_t>(GRPC_SLICE_START_PTR(compressed),
53                                           GRPC_SLICE_START_PTR(compressed) +
54                                               GRPC_SLICE_LENGTH(compressed)))
55                 .c_str(),
56             ToString(uncompressed_again).c_str());
57     abort();
58   };
59   if (!grpc_core::HuffDecoder<decltype(add)>(add,
60                                              GRPC_SLICE_START_PTR(compressed),
61                                              GRPC_SLICE_END_PTR(compressed))
62            .Run()) {
63     fail("decoding");
64   }
65   if (uncompressed_again.size() != size) {
66     fail("size mismatch");
67   }
68   if (memcmp(uncompressed_again.data(), data, size) != 0) {
69     fail("data mismatch");
70   }
71   grpc_slice_unref(uncompressed);
72   grpc_slice_unref(compressed);
73   return 0;
74 }
75