• 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 <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include <algorithm>
20 #include <cstdint>
21 #include <string>
22 #include <vector>
23 
24 #include "absl/strings/str_cat.h"
25 #include "absl/strings/str_join.h"
26 #include "absl/types/optional.h"
27 
28 #include <grpc/slice.h>
29 
30 #include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
31 #include "src/core/ext/transport/chttp2/transport/decode_huff.h"
32 
33 bool squelch = true;
34 bool leak_check = true;
35 
ToString(absl::optional<std::vector<uint8_t>> s)36 std::string ToString(absl::optional<std::vector<uint8_t>> s) {
37   if (s == absl::nullopt) return "nullopt";
38   return absl::StrCat("{", absl::StrJoin(*s, ","), "}");
39 }
40 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)41 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
42   grpc_slice uncompressed =
43       grpc_slice_from_copied_buffer(reinterpret_cast<const char*>(data), size);
44   grpc_slice compressed = grpc_chttp2_huffman_compress(uncompressed);
45   std::vector<uint8_t> uncompressed_again;
46   auto add = [&uncompressed_again](uint8_t c) {
47     uncompressed_again.push_back(c);
48   };
49   auto fail = [&](const char* reason) {
50     fprintf(stderr,
51             "Failed: %s\nuncompressed: %s\ncompressed: %s\nuncompressed_again: "
52             "%s\n",
53             reason, ToString(std::vector<uint8_t>(data, data + size)).c_str(),
54             ToString(std::vector<uint8_t>(GRPC_SLICE_START_PTR(compressed),
55                                           GRPC_SLICE_START_PTR(compressed) +
56                                               GRPC_SLICE_LENGTH(compressed)))
57                 .c_str(),
58             ToString(uncompressed_again).c_str());
59     abort();
60   };
61   if (!grpc_core::HuffDecoder<decltype(add)>(add,
62                                              GRPC_SLICE_START_PTR(compressed),
63                                              GRPC_SLICE_END_PTR(compressed))
64            .Run()) {
65     fail("decoding");
66   }
67   if (uncompressed_again.size() != size) {
68     fail("size mismatch");
69   }
70   if (memcmp(uncompressed_again.data(), data, size) != 0) {
71     fail("data mismatch");
72   }
73   grpc_slice_unref(uncompressed);
74   grpc_slice_unref(compressed);
75   return 0;
76 }
77