aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/core/end2end/fuzzers/api_fuzzer.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/core/end2end/fuzzers/api_fuzzer.c')
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer.c74
1 files changed, 40 insertions, 34 deletions
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index c1c5966801..5ccaa784a4 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -143,19 +143,6 @@ static grpc_byte_buffer *read_message(input_stream *inp) {
return out;
}
-static void read_metadata(input_stream *inp, size_t *count,
- grpc_metadata **metadata) {
- *count = next_byte(inp);
- *metadata = gpr_malloc(*count * sizeof(**metadata));
- memset(*metadata, 0, *count * sizeof(**metadata));
- for (size_t i = 0; i < *count; i++) {
- (*metadata)[i].key = read_string(inp);
- read_buffer(inp, (char **)&(*metadata)[i].value,
- &(*metadata)[i].value_length);
- (*metadata)[i].flags = read_uint32(inp);
- }
-}
-
static int read_int(input_stream *inp) { return (int)read_uint32(inp); }
static grpc_channel_args *read_args(input_stream *inp) {
@@ -366,6 +353,11 @@ typedef struct call_state {
int pending_ops;
grpc_call_details call_details;
+ // array of pointers to free later
+ size_t num_to_free;
+ size_t cap_to_free;
+ void **to_free;
+
struct call_state *next;
struct call_state *prev;
} call_state;
@@ -403,11 +395,42 @@ static call_state *maybe_delete_call_state(call_state *call) {
grpc_metadata_array_destroy(&call->recv_trailing_metadata);
gpr_free(call->recv_status_details);
grpc_call_details_destroy(&call->call_details);
+
+ for (size_t i = 0; i < call->num_to_free; i++) {
+ gpr_free(call->to_free[i]);
+ }
+ gpr_free(call->to_free);
+
gpr_free(call);
return next;
}
+static void add_to_free(call_state *call, void *p) {
+ if (call->num_to_free == call->cap_to_free) {
+ call->cap_to_free = GPR_MAX(8, 2 * call->cap_to_free);
+ call->to_free =
+ gpr_realloc(call->to_free, sizeof(*call->to_free) * call->cap_to_free);
+ }
+ call->to_free[call->num_to_free++] = p;
+}
+
+static void read_metadata(input_stream *inp, size_t *count,
+ grpc_metadata **metadata, call_state *cs) {
+ *count = next_byte(inp);
+ *metadata = gpr_malloc(*count * sizeof(**metadata));
+ memset(*metadata, 0, *count * sizeof(**metadata));
+ for (size_t i = 0; i < *count; i++) {
+ (*metadata)[i].key = read_string(inp);
+ read_buffer(inp, (char **)&(*metadata)[i].value,
+ &(*metadata)[i].value_length);
+ (*metadata)[i].flags = read_uint32(inp);
+ add_to_free(cs, (void *)(*metadata)[i].key);
+ add_to_free(cs, (void *)(*metadata)[i].value);
+ }
+ add_to_free(cs, *metadata);
+}
+
static call_state *destroy_call(call_state *call) {
grpc_call_destroy(call->call);
call->call = NULL;
@@ -688,7 +711,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
case GRPC_OP_SEND_INITIAL_METADATA:
op->op = GRPC_OP_SEND_INITIAL_METADATA;
read_metadata(&inp, &op->data.send_initial_metadata.count,
- &op->data.send_initial_metadata.metadata);
+ &op->data.send_initial_metadata.metadata,
+ g_active_call);
break;
case GRPC_OP_SEND_MESSAGE:
op->op = GRPC_OP_SEND_MESSAGE;
@@ -702,7 +726,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
read_metadata(
&inp,
&op->data.send_status_from_server.trailing_metadata_count,
- &op->data.send_status_from_server.trailing_metadata);
+ &op->data.send_status_from_server.trailing_metadata,
+ g_active_call);
op->data.send_status_from_server.status = next_byte(&inp);
op->data.send_status_from_server.status_details =
read_string(&inp);
@@ -751,30 +776,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
op = &ops[i];
switch (op->op) {
case GRPC_OP_SEND_INITIAL_METADATA:
- for (size_t j = 0; j < op->data.send_initial_metadata.count;
- j++) {
- gpr_free(
- (void *)op->data.send_initial_metadata.metadata[j].key);
- gpr_free(
- (void *)op->data.send_initial_metadata.metadata[j].value);
- }
- gpr_free(op->data.send_initial_metadata.metadata);
break;
case GRPC_OP_SEND_MESSAGE:
grpc_byte_buffer_destroy(op->data.send_message);
break;
case GRPC_OP_SEND_STATUS_FROM_SERVER:
- for (size_t j = 0;
- j < op->data.send_status_from_server.trailing_metadata_count;
- j++) {
- gpr_free((void *)op->data.send_status_from_server
- .trailing_metadata[j]
- .key);
- gpr_free((void *)op->data.send_status_from_server
- .trailing_metadata[j]
- .value);
- }
- gpr_free(op->data.send_status_from_server.trailing_metadata);
gpr_free((void *)op->data.send_status_from_server.status_details);
break;
case GRPC_OP_SEND_CLOSE_FROM_CLIENT: