From cc4445e2695f32c6836cbfd2bcd20fed0a9452ed Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 6 Apr 2022 12:31:44 -0400 Subject: [PATCH] TT#170203 allocate some strings in med_entry_t Use strdup/free for string fields in med_entry_t that are highly variable in length. This elimiates future problems if one of these fields ever has its length extended. Use g_strdup as it guarantees a non-NULL return value. Change-Id: Ia0f5883547feb62f04fcd4c5353850eb9d815413 --- mediator.c | 7 ++++++- mediator.h | 8 ++++---- medmysql.c | 8 ++++---- medredis.c | 50 +++++++++++++++++++++++++++++++++++--------------- 4 files changed, 49 insertions(+), 24 deletions(-) diff --git a/mediator.c b/mediator.c index 7444f03..ccf0d00 100644 --- a/mediator.c +++ b/mediator.c @@ -40,7 +40,12 @@ static void med_free_cache_entry(void *p) g_slice_free1(sizeof(*e), e); } void med_entry_free(void *p) { - g_slice_free1(sizeof(med_entry_t), p); + med_entry_t *e = p; + g_free(e->callid); + g_free(e->dst_leg); + g_free(e->src_leg); + g_free(e->acc_ref); + g_slice_free1(sizeof(*e), e); } /**********************************************************************/ diff --git a/mediator.h b/mediator.h index 290a785..8478eec 100644 --- a/mediator.h +++ b/mediator.h @@ -75,11 +75,11 @@ typedef enum { typedef struct { - char src_leg[1024]; - char dst_leg[1024]; + char *src_leg; + char *dst_leg; char sip_code[4]; char sip_reason[32]; - char callid[256]; + char *callid; char timestamp[24]; double unix_timestamp; char branch_id[3]; @@ -87,7 +87,7 @@ typedef struct { med_method_t method; char sip_method[32]; uint8_t redis; - char acc_ref[256]; + char *acc_ref; uint8_t timed_out; } med_entry_t; diff --git a/medmysql.c b/medmysql.c index 42eaf46..9956fd0 100644 --- a/medmysql.c +++ b/medmysql.c @@ -722,13 +722,13 @@ int medmysql_fetch_records(char *callid, g_strlcpy(e->sip_code, row[0], sizeof(e->sip_code)); g_strlcpy(e->sip_reason, row[1], sizeof(e->sip_reason)); g_strlcpy(e->sip_method, row[2], sizeof(e->sip_method)); - g_strlcpy(e->callid, row[3], sizeof(e->callid)); + e->callid = g_strdup(row[3]); g_strlcpy(e->timestamp, row[4], sizeof(e->timestamp)); e->unix_timestamp = atof(row[5]); - g_strlcpy(e->src_leg, row[6] ? : "", sizeof(e->src_leg)); - g_strlcpy(e->dst_leg, row[7] ? : "", sizeof(e->dst_leg)); + e->src_leg = g_strdup(row[6] ? : ""); + e->dst_leg = g_strdup(row[7] ? : ""); g_strlcpy(e->branch_id, row[8] ? : "", sizeof(e->branch_id)); - g_strlcpy(e->acc_ref, row[9], sizeof(e->acc_ref)); + e->acc_ref = g_strdup(row[9]); e->valid = 1; g_queue_push_tail(entries, e); diff --git a/medredis.c b/medredis.c index 90eecb2..b879fc3 100644 --- a/medredis.c +++ b/medredis.c @@ -296,22 +296,42 @@ err: return -1; } + /**********************************************************************/ static int medredis_check_reply_string(med_entry_t *entry, redisReply *reply, - char* element, const char* element_name, size_t element_size, + const char* element_name, int index, const char* cid, const char* key) { - int ret; if (reply->element[index]->type != REDIS_REPLY_STRING) { L_WARNING("Received Redis reply type %i instead of %i (string) for %s field of cid '%s' using key '%s'\n", reply->element[index]->type, REDIS_REPLY_STRING, element_name, cid, key); entry->valid = 0; - ret = -1; - } else { + return -1; + } + return 0; +} + +/**********************************************************************/ +static int medredis_check_reply_strcpy(med_entry_t *entry, redisReply *reply, + char* element, const char* element_name, size_t element_size, + int index, + const char* cid, const char* key) { + if (medredis_check_reply_string(entry, reply, element_name, index, cid, key) == 0) { g_strlcpy(element, reply->element[index]->str, element_size); - ret = 0; + return 0; } - return ret; + return -1; +} + +/**********************************************************************/ +static void medredis_check_reply_strdup(med_entry_t *entry, redisReply *reply, + char** element, const char* element_name, + int index, + const char* cid, const char* key) { + if (medredis_check_reply_string(entry, reply, element_name, index, cid, key) == 0) + *element = g_strdup(reply->element[index]->str); + else + *element = g_strdup(""); } /**********************************************************************/ @@ -354,11 +374,11 @@ static med_entry_t *medredis_reply_to_entry(redisReply *reply, const char* cid, entry->valid = 1; entry->redis = 1; - medredis_check_reply_string(entry, reply, entry->sip_code, "sip_code", sizeof(entry->sip_code), 0, cid, key); - medredis_check_reply_string(entry, reply, entry->sip_reason, "sip_reason", sizeof(entry->sip_reason), 1, cid, key); - medredis_check_reply_string(entry, reply, entry->sip_method, "sip_method", sizeof(entry->sip_method), 2, cid, key); - medredis_check_reply_string(entry, reply, entry->callid, "callid", sizeof(entry->callid), 3, cid, key); - if (medredis_check_reply_string(entry, reply, entry->timestamp, "timestamp", sizeof(entry->timestamp), 4, cid, key) != 0) { + medredis_check_reply_strcpy(entry, reply, entry->sip_code, "sip_code", sizeof(entry->sip_code), 0, cid, key); + medredis_check_reply_strcpy(entry, reply, entry->sip_reason, "sip_reason", sizeof(entry->sip_reason), 1, cid, key); + medredis_check_reply_strcpy(entry, reply, entry->sip_method, "sip_method", sizeof(entry->sip_method), 2, cid, key); + medredis_check_reply_strdup(entry, reply, &entry->callid, "callid", 3, cid, key); + if (medredis_check_reply_strcpy(entry, reply, entry->timestamp, "timestamp", sizeof(entry->timestamp), 4, cid, key) != 0) { g_strlcpy(entry->timestamp, "0000-00-00 00:00:00", sizeof(entry->timestamp)); } if (reply->element[5]->type != REDIS_REPLY_STRING) { @@ -368,15 +388,15 @@ static med_entry_t *medredis_reply_to_entry(redisReply *reply, const char* cid, } else { entry->unix_timestamp = atof(reply->element[5]->str); } - medredis_check_reply_string(entry, reply, entry->src_leg, "src_leg", sizeof(entry->src_leg), 6, cid, key); - medredis_check_reply_string(entry, reply, entry->dst_leg, "dst_leg", sizeof(entry->dst_leg), 7, cid, key); + medredis_check_reply_strdup(entry, reply, &entry->src_leg, "src_leg", 6, cid, key); + medredis_check_reply_strdup(entry, reply, &entry->dst_leg, "dst_leg", 7, cid, key); if (reply->element[8]->type != REDIS_REPLY_STRING) { L_DEBUG("Received Redis reply of cid '%s' using key '%s' doesn't have branch_id >>> old acc record version\n", cid, key); g_strlcpy(entry->branch_id, "", sizeof(entry->branch_id)); } else { - medredis_check_reply_string(entry, reply, entry->branch_id, "branch_id", sizeof(entry->branch_id), 8, cid, key); + medredis_check_reply_strcpy(entry, reply, entry->branch_id, "branch_id", sizeof(entry->branch_id), 8, cid, key); } - g_strlcpy(entry->acc_ref, key, sizeof(entry->acc_ref)); + entry->acc_ref = g_strdup(key); L_DEBUG("Converted record with cid '%s' and method '%s'\n", entry->callid, entry->sip_method);