From 549347025d47735725f97d00514acb1eb2d0c8b2 Mon Sep 17 00:00:00 2001 From: Diego Fronza Date: Fri, 27 Aug 2021 16:12:07 -0400 Subject: [PATCH] PG-223: Use memcpy and strlcpy to copy relations to counters. We redefine macro _snprintf to use memcpy, which performs better, we also update call sites using this macro to add the null terminator '\0' to the source string length, this way memcpy also correctly copies the null terminator to the destination string. We update _snprintf2 macro to use strlcpy, the reason we don't use memcpy here is because in the place where this macro is called, pgss_update_entry, only the maximum string length of REL_LEN=1000 is specified as an upper bound to copy the relations string vector to the destination counters, but since this data is string, we don't need to copy 1k bytes for every entry, by using strlcpy the copy ends as soon as the null terminator '\0' is found in the source string. --- pg_stat_monitor.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/pg_stat_monitor.c b/pg_stat_monitor.c index 2876e1b..4766de8 100644 --- a/pg_stat_monitor.c +++ b/pg_stat_monitor.c @@ -31,24 +31,14 @@ PG_MODULE_MAGIC; #define PGUNSIXBIT(val) (((val) & 0x3F) + '0') #define _snprintf(_str_dst, _str_src, _len, _max_len)\ -do \ -{ \ - int i; \ - for(i = 0; i < _len && i < _max_len; i++) \ - {\ - _str_dst[i] = _str_src[i]; \ - }\ -}while(0) + memcpy((void *)_str_dst, _str_src, _len < _max_len ? _len : _max_len) #define _snprintf2(_str_dst, _str_src, _len1, _len2)\ do \ { \ - int i,j; \ + int i; \ for(i = 0; i < _len1; i++) \ - for(j = 0; j < _len2; j++) \ - { \ - _str_dst[i][j] = _str_src[i][j]; \ - } \ + strlcpy((char *)_str_dst[i], _str_src[i], _len2); \ }while(0) /*---- Initicalization Function Declarations ----*/ @@ -1196,7 +1186,8 @@ pgss_update_entry(pgssEntry *entry, if (reset) memset(&entry->counters, 0, sizeof(Counters)); - _snprintf(e->counters.info.comments, comments, comments_len, COMMENTS_LEN); + if (comments_len > 0) + _snprintf(e->counters.info.comments, comments, comments_len + 1, COMMENTS_LEN); e->counters.state = kind; if (kind == PGSS_PLAN) { @@ -1248,8 +1239,11 @@ pgss_update_entry(pgssEntry *entry, e->counters.resp_calls[index]++; } - _snprintf(e->counters.planinfo.plan_text, plan_info->plan_text, plan_text_len, PLAN_TEXT_LEN); - _snprintf(e->counters.info.application_name, application_name, application_name_len, APPLICATIONNAME_LEN); + if (plan_text_len > 0) + _snprintf(e->counters.planinfo.plan_text, plan_info->plan_text, plan_text_len + 1, PLAN_TEXT_LEN); + + if (application_name_len > 0) + _snprintf(e->counters.info.application_name, application_name, application_name_len + 1, APPLICATIONNAME_LEN); e->counters.info.num_relations = num_relations; _snprintf2(e->counters.info.relations, relations, num_relations, REL_LEN);