From d9b5fe318acdc329f8a549917d48f8376b8b5ba1 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 18 Feb 2024 18:03:38 +0100 Subject: [PATCH] evrpc: proper NULL checks (API function return value added) Note, that in order to do this evrpc_hook_add_meta() should have return value, so this is a minor ABI change, which should not affect C ABI, but still worth to mention. Anyway this will be done in 2.2 release and unlikely RPC subsystem is popular. --- evrpc-internal.h | 2 +- evrpc.c | 61 ++++++++++++++++++++++++++++++++++---------- include/event2/rpc.h | 3 ++- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/evrpc-internal.h b/evrpc-internal.h index 9eb37638..1d97c6e0 100644 --- a/evrpc-internal.h +++ b/evrpc-internal.h @@ -118,7 +118,7 @@ struct evrpc_hook_meta { }; /* allows association of meta data with a request */ -static void evrpc_hook_associate_meta_(struct evrpc_hook_meta **pctx, +static int evrpc_hook_associate_meta_(struct evrpc_hook_meta **pctx, struct evhttp_connection *evcon); /* creates a new meta data store */ diff --git a/evrpc.c b/evrpc.c index 46bf3f7e..edbd9c1e 100644 --- a/evrpc.c +++ b/evrpc.c @@ -134,10 +134,12 @@ evrpc_add_hook(void *vbase, break; default: EVUTIL_ASSERT(hook_type == EVRPC_INPUT || hook_type == EVRPC_OUTPUT); + return NULL; } hook = mm_calloc(1, sizeof(struct evrpc_hook)); - EVUTIL_ASSERT(hook != NULL); + if (!hook) + return NULL; hook->process = cb; hook->process_arg = cb_arg; @@ -302,7 +304,9 @@ evrpc_request_cb(struct evhttp_request *req, void *arg) if (TAILQ_FIRST(&rpc->base->input_hooks) != NULL) { int hook_res; - evrpc_hook_associate_meta_(&rpc_state->hook_meta, req->evcon); + int err = evrpc_hook_associate_meta_(&rpc_state->hook_meta, req->evcon); + if (err) + goto error; /* * allow hooks to modify the outgoing request @@ -427,7 +431,9 @@ evrpc_request_done(struct evrpc_req_generic *rpc_state) if (TAILQ_FIRST(&rpc->base->output_hooks) != NULL) { int hook_res; - evrpc_hook_associate_meta_(&rpc_state->hook_meta, req->evcon); + int err = evrpc_hook_associate_meta_(&rpc_state->hook_meta, req->evcon); + if (err) + goto error; /* do hook based tweaks to the request */ hook_res = evrpc_process_hooks(&rpc->base->output_hooks, @@ -678,7 +684,9 @@ evrpc_schedule_request(struct evhttp_connection *connection, if (TAILQ_FIRST(&pool->output_hooks) != NULL) { int hook_res; - evrpc_hook_associate_meta_(&ctx->hook_meta, connection); + int err = evrpc_hook_associate_meta_(&ctx->hook_meta, connection); + if (err) + goto error; /* apply hooks to the outgoing request */ hook_res = evrpc_process_hooks(&pool->output_hooks, @@ -875,7 +883,9 @@ evrpc_reply_done(struct evhttp_request *req, void *arg) } if (TAILQ_FIRST(&pool->input_hooks) != NULL) { - evrpc_hook_associate_meta_(&ctx->hook_meta, ctx->evcon); + int err = evrpc_hook_associate_meta_(&ctx->hook_meta, ctx->evcon); + if (err) + goto error; /* apply hooks to the incoming request */ hook_res = evrpc_process_hooks(&pool->input_hooks, @@ -905,8 +915,11 @@ evrpc_reply_done(struct evhttp_request *req, void *arg) } evrpc_reply_done_closure(ctx, hook_res); - + return; /* http request is being freed by underlying layer */ + +error: + evrpc_request_wrapper_free(ctx); } static void @@ -984,7 +997,9 @@ static void evrpc_meta_data_free(struct evrpc_meta_list *meta_data) { struct evrpc_meta *entry; - EVUTIL_ASSERT(meta_data != NULL); + + if (!meta_data) + return; while ((entry = TAILQ_FIRST(meta_data)) != NULL) { TAILQ_REMOVE(meta_data, entry, next); @@ -999,7 +1014,8 @@ evrpc_hook_meta_new_(void) { struct evrpc_hook_meta *ctx; ctx = mm_malloc(sizeof(struct evrpc_hook_meta)); - EVUTIL_ASSERT(ctx != NULL); + if (!ctx) + return NULL; TAILQ_INIT(&ctx->meta_data); ctx->evcon = NULL; @@ -1007,14 +1023,17 @@ evrpc_hook_meta_new_(void) return (ctx); } -static void +static int evrpc_hook_associate_meta_(struct evrpc_hook_meta **pctx, struct evhttp_connection *evcon) { struct evrpc_hook_meta *ctx = *pctx; if (ctx == NULL) *pctx = ctx = evrpc_hook_meta_new_(); + if (!ctx) + return 1; ctx->evcon = evcon; + return 0; } static void @@ -1025,7 +1044,7 @@ evrpc_hook_context_free_(struct evrpc_hook_meta *ctx) } /* Adds meta data */ -void +int evrpc_hook_add_meta(void *ctx, const char *key, const void *data, size_t data_size) { @@ -1036,16 +1055,32 @@ evrpc_hook_add_meta(void *ctx, const char *key, if ((store = req->hook_meta) == NULL) store = req->hook_meta = evrpc_hook_meta_new_(); + if (!store) + goto err; + meta = mm_malloc(sizeof(struct evrpc_meta)); - EVUTIL_ASSERT(meta != NULL); + if (!meta) + goto err; meta->key = mm_strdup(key); - EVUTIL_ASSERT(meta->key != NULL); + if (!meta->key) + goto err; meta->data_size = data_size; meta->data = mm_malloc(data_size); - EVUTIL_ASSERT(meta->data != NULL); + if (!meta->data) + goto err; memcpy(meta->data, data, data_size); TAILQ_INSERT_TAIL(&store->meta_data, meta, next); + return 0; + +err: + evrpc_hook_context_free_(store); + if (meta) { + mm_free(meta->data); + mm_free(meta->key); + mm_free(meta); + } + return 1; } int diff --git a/include/event2/rpc.h b/include/event2/rpc.h index 9e8830c6..43d67c6b 100644 --- a/include/event2/rpc.h +++ b/include/event2/rpc.h @@ -546,9 +546,10 @@ int evrpc_resume_request(void *vbase, void *ctx, enum EVRPC_HOOK_RESULT res); * @param key a NUL-terminated c-string * @param data the data to be associated with the key * @param data_size the size of the data + * @return 0 on success or -1 on failure (in case of memory allocation failures) */ EVENT2_EXPORT_SYMBOL -void evrpc_hook_add_meta(void *ctx, const char *key, +int evrpc_hook_add_meta(void *ctx, const char *key, const void *data, size_t data_size); /** retrieves meta data previously associated