aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/postmaster/pgstat.c25
-rw-r--r--src/include/pgstat.h2
2 files changed, 22 insertions, 5 deletions
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 1ffdac5448d..9e2dce4f4c3 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -6288,10 +6288,24 @@ pgstat_db_requested(Oid databaseid)
* freed.
*/
char *
-pgstat_clip_activity(const char *activity)
+pgstat_clip_activity(const char *raw_activity)
{
- int rawlen = strnlen(activity, pgstat_track_activity_query_size - 1);
- int cliplen;
+ char *activity;
+ int rawlen;
+ int cliplen;
+
+ /*
+ * Some callers, like pgstat_get_backend_current_activity(), do not
+ * guarantee that the buffer isn't concurrently modified. We try to take
+ * care that the buffer is always terminated by a NULL byte regardless,
+ * but let's still be paranoid about the string's length. In those cases
+ * the underlying buffer is guaranteed to be
+ * pgstat_track_activity_query_size large.
+ */
+ activity = pnstrdup(raw_activity, pgstat_track_activity_query_size - 1);
+
+ /* now double-guaranteed to be NULL terminated */
+ rawlen = strlen(activity);
/*
* All supported server-encodings make it possible to determine the length
@@ -6303,5 +6317,8 @@ pgstat_clip_activity(const char *activity)
*/
cliplen = pg_mbcliplen(activity, rawlen,
pgstat_track_activity_query_size - 1);
- return pnstrdup(activity, cliplen);
+
+ activity[cliplen] = '\0';
+
+ return activity;
}
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 52af0aa5415..089b7c3a108 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -1199,7 +1199,7 @@ extern PgStat_BackendFunctionEntry *find_funcstat_entry(Oid func_id);
extern void pgstat_initstats(Relation rel);
-extern char *pgstat_clip_activity(const char *activity);
+extern char *pgstat_clip_activity(const char *raw_activity);
/* ----------
* pgstat_report_wait_start() -