diff options
Diffstat (limited to 'test/core/end2end/fuzzers/api_fuzzer.c')
-rw-r--r-- | test/core/end2end/fuzzers/api_fuzzer.c | 74 |
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: |