summaryrefslogtreecommitdiff
path: root/exec
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2023-08-12 12:50:15 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2023-08-12 12:57:35 -0700
commit5315e6e8d7e7233d54cce2b4c1bc8cf3b7acf4dc (patch)
tree5dc35aa709e829e1a67dcb868e643eee85c3449a /exec
parentf3868cb9d1806b35186eabc0262393316ebe689a (diff)
downloademacs-5315e6e8d7e7233d54cce2b4c1bc8cf3b7acf4dc.tar.gz
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.
Diffstat (limited to 'exec')
-rw-r--r--exec/configure.ac4
-rw-r--r--exec/exec.c77
2 files changed, 7 insertions, 74 deletions
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