diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2023-08-12 12:50:15 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2023-08-12 12:57:35 -0700 |
commit | 5315e6e8d7e7233d54cce2b4c1bc8cf3b7acf4dc (patch) | |
tree | 5dc35aa709e829e1a67dcb868e643eee85c3449a /exec | |
parent | f3868cb9d1806b35186eabc0262393316ebe689a (diff) | |
download | emacs-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.ac | 4 | ||||
-rw-r--r-- | exec/exec.c | 77 |
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 |