Replace remaining StrNCpy() by strlcpy()

They are equivalent, except that StrNCpy() zero-fills the entire
destination buffer instead of providing just one trailing zero.  For
all but a tiny number of callers, that's just overhead rather than
being desirable.

Remove StrNCpy() as it is now unused.

In some cases, namestrcpy() is the more appropriate function to use.
While we're here, simplify the API of namestrcpy(): Remove the return
value, don't check for NULL input.  Nothing was using that anyway.
Also, remove a few unused name-related functions.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://www.postgresql.org/message-id/flat/44f5e198-36f6-6cdb-7fa9-60e34784daae%402ndquadrant.com
This commit is contained in:
Peter Eisentraut 2020-08-10 18:51:31 +02:00
parent cec57b1a0f
commit 1784f278a6
20 changed files with 34 additions and 106 deletions

View File

@ -720,7 +720,7 @@ px_crypt_des(const char *key, const char *setting)
if (des_setkey((char *) keybuf))
return NULL;
}
StrNCpy(output, setting, 10);
strlcpy(output, setting, 10);
/*
* Double check that we weren't given a short setting. If we were, the

View File

@ -252,7 +252,7 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
*/
ctl->shared = shared;
ctl->do_fsync = true; /* default behavior */
StrNCpy(ctl->Dir, subdir, sizeof(ctl->Dir));
strlcpy(ctl->Dir, subdir, sizeof(ctl->Dir));
}
/*

View File

@ -323,7 +323,7 @@ ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOn
case 'r':
/* %r: filename of last restartpoint */
sp++;
StrNCpy(dp, lastRestartPointFname, endp - dp);
strlcpy(dp, lastRestartPointFname, endp - dp);
dp += strlen(dp);
break;
case '%':

View File

@ -484,7 +484,7 @@ ChooseConstraintName(const char *name1, const char *name2,
conDesc = table_open(ConstraintRelationId, AccessShareLock);
/* try the unmodified label first */
StrNCpy(modlabel, label, sizeof(modlabel));
strlcpy(modlabel, label, sizeof(modlabel));
for (;;)
{

View File

@ -2246,7 +2246,7 @@ ChooseRelationName(const char *name1, const char *name2,
char modlabel[NAMEDATALEN];
/* try the unmodified label first */
StrNCpy(modlabel, label, sizeof(modlabel));
strlcpy(modlabel, label, sizeof(modlabel));
for (;;)
{

View File

@ -681,7 +681,7 @@ ChooseExtendedStatisticName(const char *name1, const char *name2,
char modlabel[NAMEDATALEN];
/* try the unmodified label first */
StrNCpy(modlabel, label, sizeof(modlabel));
strlcpy(modlabel, label, sizeof(modlabel));
for (;;)
{

View File

@ -606,7 +606,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
* Truncate relname to appropriate length (probably a waste of time, as
* parser should have done this already).
*/
StrNCpy(relname, stmt->relation->relname, NAMEDATALEN);
strlcpy(relname, stmt->relation->relname, NAMEDATALEN);
/*
* Check consistency of arguments

View File

@ -4367,7 +4367,7 @@ pgstat_send_archiver(const char *xlog, bool failed)
*/
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ARCHIVER);
msg.m_failed = failed;
StrNCpy(msg.m_xlog, xlog, sizeof(msg.m_xlog));
strlcpy(msg.m_xlog, xlog, sizeof(msg.m_xlog));
msg.m_timestamp = GetCurrentTimestamp();
pgstat_send(&msg, sizeof(msg));
}

View File

@ -39,6 +39,7 @@
#include "replication/snapbuild.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
/* data for errcontext callback */
@ -288,6 +289,7 @@ CreateInitDecodingContext(const char *plugin,
{
TransactionId xmin_horizon = InvalidTransactionId;
ReplicationSlot *slot;
NameData plugin_name;
LogicalDecodingContext *ctx;
MemoryContext old_context;
@ -319,9 +321,14 @@ CreateInitDecodingContext(const char *plugin,
(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
errmsg("cannot create logical replication slot in transaction that has performed writes")));
/* register output plugin name with slot */
/*
* Register output plugin name with slot. We need the mutex to avoid
* concurrent reading of a partially copied string. But we don't want any
* complicated code while holding a spinlock, so do namestrcpy() outside.
*/
namestrcpy(&plugin_name, plugin);
SpinLockAcquire(&slot->mutex);
StrNCpy(NameStr(slot->data.plugin), plugin, NAMEDATALEN);
slot->data.plugin = plugin_name;
SpinLockRelease(&slot->mutex);
if (XLogRecPtrIsInvalid(restart_lsn))

View File

@ -275,7 +275,7 @@ ReplicationSlotCreate(const char *name, bool db_specific,
/* first initialize persistent data */
memset(&slot->data, 0, sizeof(ReplicationSlotPersistentData));
StrNCpy(NameStr(slot->data.name), name, NAMEDATALEN);
namestrcpy(&slot->data.name, name);
slot->data.database = db_specific ? MyDatabaseId : InvalidOid;
slot->data.persistency = persistency;

View File

@ -3890,7 +3890,7 @@ DCH_cache_getnew(const char *str, bool std)
elog(DEBUG_elog_output, "OLD: '%s' AGE: %d", old->str, old->age);
#endif
old->valid = false;
StrNCpy(old->str, str, DCH_CACHE_SIZE + 1);
strlcpy(old->str, str, DCH_CACHE_SIZE + 1);
old->age = (++DCHCounter);
/* caller is expected to fill format, then set valid */
return old;
@ -3904,7 +3904,7 @@ DCH_cache_getnew(const char *str, bool std)
DCHCache[n_DCHCache] = ent = (DCHCacheEntry *)
MemoryContextAllocZero(TopMemoryContext, sizeof(DCHCacheEntry));
ent->valid = false;
StrNCpy(ent->str, str, DCH_CACHE_SIZE + 1);
strlcpy(ent->str, str, DCH_CACHE_SIZE + 1);
ent->std = std;
ent->age = (++DCHCounter);
/* caller is expected to fill format, then set valid */
@ -4799,7 +4799,7 @@ NUM_cache_getnew(const char *str)
elog(DEBUG_elog_output, "OLD: \"%s\" AGE: %d", old->str, old->age);
#endif
old->valid = false;
StrNCpy(old->str, str, NUM_CACHE_SIZE + 1);
strlcpy(old->str, str, NUM_CACHE_SIZE + 1);
old->age = (++NUMCounter);
/* caller is expected to fill format and Num, then set valid */
return old;
@ -4813,7 +4813,7 @@ NUM_cache_getnew(const char *str)
NUMCache[n_NUMCache] = ent = (NUMCacheEntry *)
MemoryContextAllocZero(TopMemoryContext, sizeof(NUMCacheEntry));
ent->valid = false;
StrNCpy(ent->str, str, NUM_CACHE_SIZE + 1);
strlcpy(ent->str, str, NUM_CACHE_SIZE + 1);
ent->age = (++NUMCounter);
/* caller is expected to fill format and Num, then set valid */
++n_NUMCache;

View File

@ -229,54 +229,14 @@ btnamesortsupport(PG_FUNCTION_ARGS)
* MISCELLANEOUS PUBLIC ROUTINES *
*****************************************************************************/
int
namecpy(Name n1, const NameData *n2)
{
if (!n1 || !n2)
return -1;
StrNCpy(NameStr(*n1), NameStr(*n2), NAMEDATALEN);
return 0;
}
#ifdef NOT_USED
int
namecat(Name n1, Name n2)
{
return namestrcat(n1, NameStr(*n2)); /* n2 can't be any longer than n1 */
}
#endif
int
void
namestrcpy(Name name, const char *str)
{
if (!name || !str)
return -1;
StrNCpy(NameStr(*name), str, NAMEDATALEN);
return 0;
/* NB: We need to zero-pad the destination. */
strncpy(NameStr(*name), str, NAMEDATALEN);
NameStr(*name)[NAMEDATALEN-1] = '\0';
}
#ifdef NOT_USED
int
namestrcat(Name name, const char *str)
{
int i;
char *p,
*q;
if (!name || !str)
return -1;
for (i = 0, p = NameStr(*name); i < NAMEDATALEN && *p; ++i, ++p)
;
for (q = str; i < NAMEDATALEN; ++i, ++p, ++q)
{
*p = *q;
if (!*q)
break;
}
return 0;
}
#endif
/*
* Compare a NAME to a C string
*

View File

@ -75,16 +75,7 @@
#endif
#ifdef WIN32
/*
* This Windows file defines StrNCpy. We don't need it here, so we undefine
* it to keep the compiler quiet, and undefine it again after the file is
* included, so we don't accidentally use theirs.
*/
#undef StrNCpy
#include <shlwapi.h>
#ifdef StrNCpy
#undef StrNCpy
#endif
#endif
#define MAX_L10N_DATA 80

View File

@ -2489,7 +2489,7 @@ pg_get_userbyid(PG_FUNCTION_ARGS)
if (HeapTupleIsValid(roletup))
{
role_rec = (Form_pg_authid) GETSTRUCT(roletup);
StrNCpy(NameStr(*result), NameStr(role_rec->rolname), NAMEDATALEN);
*result = role_rec->rolname;
ReleaseSysCache(roletup);
}
else

View File

@ -144,7 +144,7 @@ find_my_exec(const char *argv0, char *retpath)
if (first_dir_separator(argv0) != NULL)
{
if (is_absolute_path(argv0))
StrNCpy(retpath, argv0, MAXPGPATH);
strlcpy(retpath, argv0, MAXPGPATH);
else
join_path_components(retpath, cwd, argv0);
canonicalize_path(retpath);
@ -184,7 +184,7 @@ find_my_exec(const char *argv0, char *retpath)
if (!endp)
endp = startp + strlen(startp); /* point to end */
StrNCpy(test_path, startp, Min(endp - startp + 1, MAXPGPATH));
strlcpy(test_path, startp, Min(endp - startp + 1, MAXPGPATH));
if (is_absolute_path(test_path))
join_path_components(retpath, test_path, argv0);

View File

@ -932,35 +932,6 @@ extern void ExceptionalCondition(const char *conditionName,
*/
#define Abs(x) ((x) >= 0 ? (x) : -(x))
/*
* StrNCpy
* Like standard library function strncpy(), except that result string
* is guaranteed to be null-terminated --- that is, at most N-1 bytes
* of the source string will be kept.
* Also, the macro returns no result (too hard to do that without
* evaluating the arguments multiple times, which seems worse).
*
* BTW: when you need to copy a non-null-terminated string (like a text
* datum) and add a null, do not do it with StrNCpy(..., len+1). That
* might seem to work, but it fetches one byte more than there is in the
* text object. One fine day you'll have a SIGSEGV because there isn't
* another byte before the end of memory. Don't laugh, we've had real
* live bug reports from real live users over exactly this mistake.
* Do it honestly with "memcpy(dst,src,len); dst[len] = '\0';", instead.
*/
#define StrNCpy(dst,src,len) \
do \
{ \
char * _dst = (dst); \
Size _len = (len); \
\
if (_len > 0) \
{ \
strncpy(_dst, (src), _len); \
_dst[_len-1] = '\0'; \
} \
} while (0)
/* Get a bit mask of the bits set in non-long aligned addresses */
#define LONG_ALIGN_MASK (sizeof(long) - 1)

View File

@ -39,8 +39,7 @@ extern uint64 hex_decode(const char *src, size_t len, char *dst);
extern int2vector *buildint2vector(const int16 *int2s, int n);
/* name.c */
extern int namecpy(Name n1, const NameData *n2);
extern int namestrcpy(Name name, const char *str);
extern void namestrcpy(Name name, const char *str);
extern int namestrcmp(Name name, const char *str);
/* numutils.c */

View File

@ -1015,7 +1015,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm *tm, char **tzn)
* Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
* contains an error message, which doesn't fit in the buffer
*/
StrNCpy(*tzn, tm->tm_zone, MAXTZLEN + 1);
strlcpy(*tzn, tm->tm_zone, MAXTZLEN + 1);
if (strlen(tm->tm_zone) > MAXTZLEN)
tm->tm_isdst = -1;
}
@ -1033,7 +1033,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm *tm, char **tzn)
* Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
* contains an error message, which doesn't fit in the buffer
*/
StrNCpy(*tzn, TZNAME_GLOBAL[tm->tm_isdst], MAXTZLEN + 1);
strlcpy(*tzn, TZNAME_GLOBAL[tm->tm_isdst], MAXTZLEN + 1);
if (strlen(TZNAME_GLOBAL[tm->tm_isdst]) > MAXTZLEN)
tm->tm_isdst = -1;
}

View File

@ -63,7 +63,7 @@ ecpg_filter(const char *sourcefile, const char *outfile)
if (plen > 1)
{
n = (char *) malloc(plen);
StrNCpy(n, p + 1, plen);
strlcpy(n, p + 1, plen);
replace_string(linebuf, n, "");
}
}

View File

@ -74,7 +74,7 @@ rot13_passphrase(char *buf, int size, int rwflag, void *userdata)
{
Assert(ssl_passphrase != NULL);
StrNCpy(buf, ssl_passphrase, size);
strlcpy(buf, ssl_passphrase, size);
for (char *p = buf; *p; p++)
{
char c = *p;