Avoid stpncpy

It’s not worth the porting hassle, and as the glibc manual says,
“this function is generally a poor choice for processing strings”.
* admin/merge-gnulib (GNULIB_MODULES): Remove stpncpy.
* exec/configure.ac: Do not check for stpncpy.
* exec/exec.c (rpl_stpncpy, stpncpy): Remove this replacement.
(exec_0): Properly clear buffer1.  Use memcpy instead of
stpncpy to add the trailing name.  This code is clearly
still suboptimal but efficiency is not that important here
and I tried to minimize the change.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
This commit is contained in:
Paul Eggert
2023-08-12 12:50:15 -07:00
parent f3868cb9d1
commit 5315e6e8d7
7 changed files with 8 additions and 297 deletions

View File

@@ -62,8 +62,8 @@ AC_TYPE_SSIZE_T
AC_TYPE_PID_T
AC_HEADER_STDBOOL
AC_CHECK_FUNCS([getpagesize stpcpy stpncpy])
AC_CHECK_DECLS([stpcpy, stpncpy])
AC_CHECK_FUNCS([getpagesize stpcpy])
AC_CHECK_DECLS([stpcpy])
AC_CHECK_FUNC([process_vm_readv],
[AC_CHECK_FUNC([process_vm_writev],
[AC_CHECK_DECL([process_vm_readv],

View File

@@ -66,74 +66,6 @@ rpl_stpcpy (char *dest, const char *src)
#define stpcpy rpl_stpcpy
#endif /* !defined HAVE_STPCPY || !defined HAVE_DECL_STPCPY */
#if !defined HAVE_STPNCPY || !defined HAVE_DECL_STPNCPY
/* Copy no more than N bytes of SRC to DST, returning a pointer past
the last non-NUL byte written into DST. */
static char *
rpl_stpncpy (char *dest, const char *src, size_t n)
{
char c, *s;
size_t n4;
s = dest;
if (n >= 4)
{
n4 = n >> 2;
for (;;)
{
c = *src++;
*dest++ = c;
if (c == '\0')
break;
c = *src++;
*dest++ = c;
if (c == '\0')
break;
c = *src++;
*dest++ = c;
if (c == '\0')
break;
c = *src++;
*dest++ = c;
if (c == '\0')
break;
if (--n4 == 0)
goto last_chars;
}
n -= dest - s;
goto zero_fill;
}
last_chars:
n &= 3;
if (n == 0)
return dest;
for (;;)
{
c = *src++;
--n;
*dest++ = c;
if (c == '\0')
break;
if (n == 0)
return dest;
}
zero_fill:
while (n-- > 0)
dest[n] = '\0';
return dest - 1;
}
#define stpncpy rpl_stpncpy
#endif /* !defined HAVE_STPNCPY || !defined HAVE_DECL_STPNCPY */
/* Executable reading functions.
@@ -1005,13 +937,14 @@ exec_0 (char *name, struct exec_tracee *tracee,
else
{
/* If name is not absolute, then make it relative to TRACEE's
cwd. Use stpcpy, as sprintf is not reentrant. */
cwd. Do not use sprintf at it is not reentrant and it
mishandles results longer than INT_MAX. */
if (name[0] && name[0] != '/')
{
/* Clear `buffer'. */
/* Clear both buffers. */
memset (buffer, 0, sizeof buffer);
memset (buffer1, 0, sizeof buffer);
memset (buffer1, 0, sizeof buffer1);
/* Copy over /proc, the PID, and /cwd/. */
rewrite = stpcpy (buffer, "/proc/");
@@ -1042,7 +975,7 @@ exec_0 (char *name, struct exec_tracee *tracee,
rewrite = buffer1 + link_size;
remaining = buffer1 + sizeof buffer1 - rewrite - 1;
rewrite = stpncpy (rewrite, name, remaining);
memcpy (rewrite, name, strnlen (name, remaining));
/* Replace name with buffer1. */
#ifndef REENTRANT