Hi,

There are some places, where strlen can have an overhead.
This patch tries to fix this.

Pass check-world at linux ubuntu (20.04) 64 bits.

regards,
Ranier Vilela
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index c14ca27c5e..2036072990 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -2443,11 +2443,11 @@ ChooseIndexColumnNames(List *indexElems)
 			if (lc2 == NULL)
 				break;			/* found nonconflicting name */
 
-			sprintf(nbuf, "%d", i);
+			nlen = sprintf(nbuf, "%d", i);
 
 			/* Ensure generated names are shorter than NAMEDATALEN */
 			nlen = pg_mbcliplen(origname, strlen(origname),
-								NAMEDATALEN - 1 - strlen(nbuf));
+								NAMEDATALEN - 1 - nlen);
 			memcpy(buf, origname, nlen);
 			strcpy(buf + nlen, nbuf);
 			curname = buf;
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 8cc23ef7fb..4619f3887e 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -3014,6 +3014,8 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 	uint8		encryptedpassword[RADIUS_MAX_PASSWORD_LENGTH];
 	uint8	   *md5trailer;
 	int			packetlength;
+	size_t      secretlen;
+	size_t		passwdlen;
 	pgsocket	sock;
 
 #ifdef HAVE_IPV6
@@ -3077,15 +3079,17 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 	 * and then: e[i] = p[i] XOR MD5(secret + e[i-1]) for the following ones
 	 * (if necessary)
 	 */
-	encryptedpasswordlen = ((strlen(passwd) + RADIUS_VECTOR_LENGTH - 1) / RADIUS_VECTOR_LENGTH) * RADIUS_VECTOR_LENGTH;
-	cryptvector = palloc(strlen(secret) + RADIUS_VECTOR_LENGTH);
-	memcpy(cryptvector, secret, strlen(secret));
+	secretlen = strlen(secret);
+	passwdlen = strlen(passwd);
+	encryptedpasswordlen = ((passwdlen + RADIUS_VECTOR_LENGTH - 1) / RADIUS_VECTOR_LENGTH) * RADIUS_VECTOR_LENGTH;
+	cryptvector = palloc(secretlen + RADIUS_VECTOR_LENGTH);
+	memcpy(cryptvector, secret, secretlen);
 
 	/* for the first iteration, we use the Request Authenticator vector */
 	md5trailer = packet->vector;
 	for (i = 0; i < encryptedpasswordlen; i += RADIUS_VECTOR_LENGTH)
 	{
-		memcpy(cryptvector + strlen(secret), md5trailer, RADIUS_VECTOR_LENGTH);
+		memcpy(cryptvector + secretlen, md5trailer, RADIUS_VECTOR_LENGTH);
 
 		/*
 		 * .. and for subsequent iterations the result of the previous XOR
@@ -3093,7 +3097,7 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 		 */
 		md5trailer = encryptedpassword + i;
 
-		if (!pg_md5_binary(cryptvector, strlen(secret) + RADIUS_VECTOR_LENGTH, encryptedpassword + i))
+		if (!pg_md5_binary(cryptvector, secretlen + RADIUS_VECTOR_LENGTH, encryptedpassword + i))
 		{
 			ereport(LOG,
 					(errmsg("could not perform MD5 encryption of password")));
@@ -3104,7 +3108,7 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 
 		for (j = i; j < i + RADIUS_VECTOR_LENGTH; j++)
 		{
-			if (j < strlen(passwd))
+			if (j < passwdlen)
 				encryptedpassword[j] = passwd[j] ^ encryptedpassword[j];
 			else
 				encryptedpassword[j] = '\0' ^ encryptedpassword[j];
@@ -3286,7 +3290,7 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 		 * Verify the response authenticator, which is calculated as
 		 * MD5(Code+ID+Length+RequestAuthenticator+Attributes+Secret)
 		 */
-		cryptvector = palloc(packetlength + strlen(secret));
+		cryptvector = palloc(packetlength + secretlen);
 
 		memcpy(cryptvector, receivepacket, 4);	/* code+id+length */
 		memcpy(cryptvector + 4, packet->vector, RADIUS_VECTOR_LENGTH);	/* request
@@ -3295,10 +3299,10 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por
 		if (packetlength > RADIUS_HEADER_LENGTH)	/* there may be no
 													 * attributes at all */
 			memcpy(cryptvector + RADIUS_HEADER_LENGTH, receive_buffer + RADIUS_HEADER_LENGTH, packetlength - RADIUS_HEADER_LENGTH);
-		memcpy(cryptvector + packetlength, secret, strlen(secret));
+		memcpy(cryptvector + packetlength, secret, secretlen);
 
 		if (!pg_md5_binary(cryptvector,
-						   packetlength + strlen(secret),
+						   packetlength + secretlen,
 						   encryptedpassword))
 		{
 			ereport(LOG,
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 122c2b05bd..7c8069cbe1 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -4277,10 +4277,11 @@ static void
 report_fork_failure_to_client(Port *port, int errnum)
 {
 	char		buffer[1000];
+	size_t		buflen;
 	int			rc;
 
 	/* Format the error message packet (always V2 protocol) */
-	snprintf(buffer, sizeof(buffer), "E%s%s\n",
+	buflen = snprintf(buffer, sizeof(buffer), "E%s%s\n",
 			 _("could not fork new process for connection: "),
 			 strerror(errnum));
 
@@ -4291,7 +4292,7 @@ report_fork_failure_to_client(Port *port, int errnum)
 	/* We'll retry after EINTR, but ignore all other failures */
 	do
 	{
-		rc = send(port->sock, buffer, strlen(buffer) + 1, 0);
+		rc = send(port->sock, buffer, buflen + 1, 0);
 	} while (rc < 0 && errno == EINTR);
 }
 
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index e09108d0ec..9b11030890 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -953,10 +953,11 @@ static void
 send_int8_string(StringInfoData *buf, int64 intval)
 {
 	char		is[32];
+	size_t		islen;
 
-	sprintf(is, INT64_FORMAT, intval);
-	pq_sendint32(buf, strlen(is));
-	pq_sendbytes(buf, is, strlen(is));
+	islen = sprintf(is, INT64_FORMAT, intval);
+	pq_sendint32(buf, islen);
+	pq_sendbytes(buf, is, islen);
 }
 
 static void
diff --git a/src/backend/storage/file/reinit.c b/src/backend/storage/file/reinit.c
index 40c758d789..8caff217ed 100644
--- a/src/backend/storage/file/reinit.c
+++ b/src/backend/storage/file/reinit.c
@@ -268,6 +268,8 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
 	 */
 	if ((op & UNLOGGED_RELATION_INIT) != 0)
 	{
+		size_t namelen = strlen(forkNames[INIT_FORKNUM]);
+
 		/* Scan the directory. */
 		dbspace_dir = AllocateDir(dbspacedirname);
 		while ((de = ReadDir(dbspace_dir, dbspacedirname)) != NULL)
@@ -296,7 +298,7 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
 			oidbuf[oidchars] = '\0';
 			snprintf(dstpath, sizeof(dstpath), "%s/%s%s",
 					 dbspacedirname, oidbuf, de->d_name + oidchars + 1 +
-					 strlen(forkNames[INIT_FORKNUM]));
+					 namelen);
 
 			/* OK, we're ready to perform the actual copy. */
 			elog(DEBUG2, "copying %s to %s", srcpath, dstpath);
@@ -334,7 +336,7 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op)
 			oidbuf[oidchars] = '\0';
 			snprintf(mainpath, sizeof(mainpath), "%s/%s%s",
 					 dbspacedirname, oidbuf, de->d_name + oidchars + 1 +
-					 strlen(forkNames[INIT_FORKNUM]));
+					 namelen);
 
 			fsync_fname(mainpath, false);
 		}
diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c
index d093ce8038..686fdc550b 100644
--- a/src/backend/utils/adt/cash.c
+++ b/src/backend/utils/adt/cash.c
@@ -313,6 +313,7 @@ cash_out(PG_FUNCTION_ARGS)
 	char	   *result;
 	char		buf[128];
 	char	   *bufptr;
+	size_t		len;
 	int			digit_pos;
 	int			points,
 				mon_group;
@@ -378,6 +379,7 @@ cash_out(PG_FUNCTION_ARGS)
 	 * current digit position, with zero as the digit just left of the decimal
 	 * point, increasing to the right.
 	 */
+	len = strlen(ssymbol);
 	digit_pos = points;
 	do
 	{
@@ -389,8 +391,8 @@ cash_out(PG_FUNCTION_ARGS)
 		else if (digit_pos < 0 && (digit_pos % mon_group) == 0)
 		{
 			/* insert thousands sep, but only to left of radix point */
-			bufptr -= strlen(ssymbol);
-			memcpy(bufptr, ssymbol, strlen(ssymbol));
+			bufptr -= len;
+			memcpy(bufptr, ssymbol, len);
 		}
 
 		*(--bufptr) = ((uint64) value % 10) + '0';
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index a2e0f8de7e..7ab9b9d67b 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -11163,6 +11163,7 @@ GUCArrayDelete(ArrayType *array, const char *name)
 {
 	struct config_generic *record;
 	ArrayType  *newarray;
+	size_t      namelen;
 	int			i;
 	int			index;
 
@@ -11182,6 +11183,7 @@ GUCArrayDelete(ArrayType *array, const char *name)
 
 	newarray = NULL;
 	index = 1;
+	namelen = strlen(name);
 
 	for (i = 1; i <= ARR_DIMS(array)[0]; i++)
 	{
@@ -11200,8 +11202,8 @@ GUCArrayDelete(ArrayType *array, const char *name)
 		val = TextDatumGetCString(d);
 
 		/* ignore entry if it's what we want to delete */
-		if (strncmp(val, name, strlen(name)) == 0
-			&& val[strlen(name)] == '=')
+		if (strncmp(val, name, namelen) == 0
+			&& val[namelen] == '=')
 			continue;
 
 		/* else add it to the output array */
@@ -12098,15 +12100,16 @@ assign_pgstat_temp_directory(const char *newval, void *extra)
 	char	   *dname;
 	char	   *tname;
 	char	   *fname;
+	size_t		newvallen = strlen(newval);
 
 	/* directory */
-	dname = guc_malloc(ERROR, strlen(newval) + 1);	/* runtime dir */
+	dname = guc_malloc(ERROR, newvallen + 1);	/* runtime dir */
 	sprintf(dname, "%s", newval);
 
 	/* global stats */
-	tname = guc_malloc(ERROR, strlen(newval) + 12); /* /global.tmp */
+	tname = guc_malloc(ERROR, newvallen + 12); /* /global.tmp */
 	sprintf(tname, "%s/global.tmp", newval);
-	fname = guc_malloc(ERROR, strlen(newval) + 13); /* /global.stat */
+	fname = guc_malloc(ERROR, newvallen + 13); /* /global.stat */
 	sprintf(fname, "%s/global.stat", newval);
 
 	if (pgstat_stat_directory)
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index e950b41374..da76fc56e0 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -5153,6 +5153,7 @@ parseServiceFile(const char *serviceFile,
 				 PQExpBuffer errorMessage,
 				 bool *group_found)
 {
+	size_t		servicelen;
 	int			result = 0,
 				linenr = 0,
 				i;
@@ -5170,13 +5171,15 @@ parseServiceFile(const char *serviceFile,
 		return 1;
 	}
 
+	servicelen = strlen(service);
 	while ((line = fgets(buf, sizeof(buf), f)) != NULL)
 	{
 		int			len;
 
 		linenr++;
 
-		if (strlen(line) >= sizeof(buf) - 1)
+		len = strlen(line);
+		if (len >= sizeof(buf) - 1)
 		{
 			appendPQExpBuffer(errorMessage,
 							  libpq_gettext("line %d too long in service file \"%s\"\n"),
@@ -5187,7 +5190,6 @@ parseServiceFile(const char *serviceFile,
 		}
 
 		/* ignore whitespace at end of line, especially the newline */
-		len = strlen(line);
 		while (len > 0 && isspace((unsigned char) line[len - 1]))
 			line[--len] = '\0';
 
@@ -5208,8 +5210,8 @@ parseServiceFile(const char *serviceFile,
 				goto exit;
 			}
 
-			if (strncmp(line + 1, service, strlen(service)) == 0 &&
-				line[strlen(service) + 1] == ']')
+			if (strncmp(line + 1, service, servicelen) == 0 &&
+				line[servicelen + 1] == ']')
 				*group_found = true;
 			else
 				*group_found = false;

Reply via email to