Coverage Report

Created: 2026-01-10 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nghttp2/fuzz/fuzz_frames.cc
Line
Count
Source
1
#include <string>
2
#include <fuzzer/FuzzedDataProvider.h>
3
4
extern "C" {
5
#include <string.h>
6
#include "nghttp2_hd.h"
7
#include "nghttp2_frame.h"
8
9
#include "nghttp2_test_helper.h"
10
11
87.6k
#define HEADERS_LENGTH 7
12
13
34.1k
static nghttp2_nv fuzz_make_nv(std::string s1, std::string s2) {
14
34.1k
  nghttp2_nv nv;
15
34.1k
  uint8_t *n = (uint8_t *)malloc(s1.size());
16
34.1k
  memcpy(n, s1.c_str(), s1.size());
17
18
34.1k
  uint8_t *v = (uint8_t *)malloc(s2.size());
19
34.1k
  memcpy(v, s2.c_str(), s2.size());
20
21
34.1k
  nv.name = n;
22
34.1k
  nv.value = v;
23
34.1k
  nv.namelen = s1.size();
24
34.1k
  nv.valuelen = s2.size();
25
34.1k
  nv.flags = NGHTTP2_NV_FLAG_NONE;
26
27
34.1k
  return nv;
28
34.1k
}
29
30
34.1k
static void fuzz_free_nv(nghttp2_nv *nv) {
31
34.1k
  free(nv->name);
32
34.1k
  free(nv->value);
33
34.1k
}
34
35
2.43k
void check_frame_pack_headers(FuzzedDataProvider *data_provider) {
36
2.43k
  nghttp2_hd_deflater deflater;
37
2.43k
  nghttp2_hd_inflater inflater;
38
2.43k
  nghttp2_headers frame, oframe;
39
2.43k
  nghttp2_bufs bufs;
40
2.43k
  nghttp2_nv *nva;
41
2.43k
  nghttp2_priority_spec pri_spec;
42
2.43k
  size_t nvlen;
43
2.43k
  nva_out out;
44
2.43k
  size_t hdblocklen;
45
2.43k
  int rv;
46
2.43k
  nghttp2_mem *mem;
47
48
2.43k
  mem = nghttp2_mem_default();
49
2.43k
  frame_pack_bufs_init(&bufs);
50
51
2.43k
  nva_out_init(&out);
52
2.43k
  nghttp2_hd_deflate_init(&deflater, mem);
53
2.43k
  nghttp2_hd_inflate_init(&inflater, mem);
54
55
  /* Create a set of headers seeded with data from the fuzzer */
56
2.43k
  nva = (nghttp2_nv *)mem->malloc(sizeof(nghttp2_nv) * HEADERS_LENGTH, NULL);
57
19.4k
  for (int i = 0; i < HEADERS_LENGTH; i++) {
58
17.0k
    nva[i] = fuzz_make_nv(data_provider->ConsumeRandomLengthString(30),
59
17.0k
                          data_provider->ConsumeRandomLengthString(300));
60
17.0k
  }
61
62
2.43k
  nvlen = HEADERS_LENGTH;
63
2.43k
  nghttp2_priority_spec_default_init(&pri_spec);
64
2.43k
  nghttp2_frame_headers_init(
65
2.43k
    &frame, NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS, 1000000007,
66
2.43k
    NGHTTP2_HCAT_REQUEST, &pri_spec, nva, nvlen);
67
68
  /* Perform a set of operations with the fuzz data */
69
2.43k
  rv = nghttp2_frame_pack_headers(&bufs, &frame, &deflater);
70
2.43k
  if (rv == 0) {
71
2.43k
    unpack_framebuf((nghttp2_frame *)&oframe, &bufs);
72
73
2.43k
    inflate_hd(&inflater, &out, &bufs, NGHTTP2_FRAME_HDLEN, mem);
74
2.43k
    nva_out_reset(&out, mem);
75
2.43k
    nghttp2_bufs_reset(&bufs);
76
2.43k
  }
77
78
2.43k
  nghttp2_nv *nva2 = NULL;
79
2.43k
  rv = nghttp2_nv_array_copy(&nva2, nva, nvlen, mem);
80
2.43k
  if (rv == 0) {
81
2.43k
    nghttp2_nv_array_del(nva2, mem);
82
2.43k
  }
83
84
  /* Cleanup */
85
19.4k
  for (int i = 0; i < HEADERS_LENGTH; i++) {
86
17.0k
    fuzz_free_nv(&nva[i]);
87
17.0k
  }
88
89
2.43k
  nghttp2_bufs_free(&bufs);
90
2.43k
  nghttp2_frame_headers_free(&frame, mem);
91
2.43k
  nghttp2_hd_inflate_free(&inflater);
92
2.43k
  nghttp2_hd_deflate_free(&deflater);
93
2.43k
}
94
95
2.43k
void check_frame_push_promise(FuzzedDataProvider *data_provider) {
96
2.43k
  nghttp2_hd_deflater deflater;
97
2.43k
  nghttp2_hd_inflater inflater;
98
2.43k
  nghttp2_push_promise frame, oframe;
99
2.43k
  nghttp2_bufs bufs;
100
2.43k
  nghttp2_nv *nva;
101
2.43k
  nghttp2_priority_spec pri_spec;
102
2.43k
  size_t nvlen;
103
2.43k
  nva_out out;
104
2.43k
  size_t hdblocklen;
105
2.43k
  int rv;
106
2.43k
  nghttp2_mem *mem;
107
108
2.43k
  mem = nghttp2_mem_default();
109
2.43k
  frame_pack_bufs_init(&bufs);
110
111
2.43k
  nva_out_init(&out);
112
2.43k
  nghttp2_hd_deflate_init(&deflater, mem);
113
2.43k
  nghttp2_hd_inflate_init(&inflater, mem);
114
115
  /* Create a set of headers seeded with data from the fuzzer */
116
2.43k
  nva = (nghttp2_nv *)mem->malloc(sizeof(nghttp2_nv) * HEADERS_LENGTH, NULL);
117
19.4k
  for (int i = 0; i < HEADERS_LENGTH; i++) {
118
17.0k
    nva[i] = fuzz_make_nv(data_provider->ConsumeRandomLengthString(30),
119
17.0k
                          data_provider->ConsumeRandomLengthString(300));
120
17.0k
  }
121
2.43k
  nvlen = HEADERS_LENGTH;
122
2.43k
  nghttp2_priority_spec_default_init(&pri_spec);
123
124
  /* Perform a set of operations with the fuzz data */
125
2.43k
  nghttp2_frame_push_promise_init(&frame, NGHTTP2_FLAG_END_HEADERS, 1000000007,
126
2.43k
                                  (1U << 31) - 1, nva, nvlen);
127
128
2.43k
  rv = nghttp2_frame_pack_push_promise(&bufs, &frame, &deflater);
129
2.43k
  if (rv == 0) {
130
2.43k
    unpack_framebuf((nghttp2_frame *)&oframe, &bufs);
131
2.43k
  }
132
133
2.43k
  nghttp2_nv *nva2 = NULL;
134
2.43k
  rv = nghttp2_nv_array_copy(&nva2, nva, nvlen, mem);
135
2.43k
  if (rv == 0) {
136
2.43k
    nghttp2_nv_array_del(nva2, mem);
137
2.43k
  }
138
139
  /* Cleanup */
140
19.4k
  for (int i = 0; i < HEADERS_LENGTH; i++) {
141
17.0k
    fuzz_free_nv(&nva[i]);
142
17.0k
  }
143
144
2.43k
  nghttp2_bufs_reset(&bufs);
145
2.43k
  nghttp2_bufs_free(&bufs);
146
147
2.43k
  nghttp2_frame_push_promise_free(&frame, mem);
148
2.43k
  nghttp2_hd_inflate_free(&inflater);
149
2.43k
  nghttp2_hd_deflate_free(&deflater);
150
2.43k
}
151
152
13.7k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
153
13.7k
  FuzzedDataProvider data_provider(data, size);
154
155
13.7k
  check_frame_pack_headers(&data_provider);
156
13.7k
  check_frame_push_promise(&data_provider);
157
13.7k
  return 0;
158
13.7k
}
159
160
} // extern C