Avoid use of non-portable strnlen() in pgstat_clip_activity().
authorAndres Freund <andres@anarazel.de>
Tue, 19 Sep 2017 21:17:20 +0000 (14:17 -0700)
committerAndres Freund <andres@anarazel.de>
Tue, 19 Sep 2017 21:25:47 +0000 (14:25 -0700)
The use of strnlen rather than strlen was just paranoia. Instead of
giving up on the paranoia, just implement the safeguard
differently. And add a comment explaining why we're careful.

Author: Andres Freund
Discussion: https://postgr.es/m/E1duOkJ-0001Mc-U5@gemulon.postgresql.org

src/backend/postmaster/pgstat.c
src/include/pgstat.h

index 1ffdac5448d9c45aad021ebd54f01ab1f523aba5..9e2dce4f4c356bd7a85a8c34fc74bdb86ced4d73 100644 (file)
@@ -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;
 }
index 52af0aa5415b1e615f3087c8627a728bc3a8d557..089b7c3a1088bcb5decb5c4c55cb1300e900b083 100644 (file)
@@ -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() -