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;