From 5315e6e8d7e7233d54cce2b4c1bc8cf3b7acf4dc Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 12 Aug 2023 12:50:15 -0700 Subject: Avoid stpncpy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- exec/configure.ac | 4 +-- exec/exec.c | 77 ++++--------------------------------------------------- 2 files changed, 7 insertions(+), 74 deletions(-) (limited to 'exec') diff --git a/exec/configure.ac b/exec/configure.ac index e78d8ebea90..180c200d13d 100644 --- a/exec/configure.ac +++ b/exec/configure.ac @@ -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], diff --git a/exec/exec.c b/exec/exec.c index 935c94a59af..dae05755675 100644 --- a/exec/exec.c +++ b/exec/exec.c @@ -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 -- cgit v1.2.3