aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2023-08-12 12:50:15 -0700
committerPaul Eggert2023-08-12 12:57:35 -0700
commit5315e6e8d7e7233d54cce2b4c1bc8cf3b7acf4dc (patch)
tree5dc35aa709e829e1a67dcb868e643eee85c3449a
parentf3868cb9d1806b35186eabc0262393316ebe689a (diff)
downloademacs-5315e6e8d7e7233d54cce2b4c1bc8cf3b7acf4dc.tar.gz
emacs-5315e6e8d7e7233d54cce2b4c1bc8cf3b7acf4dc.zip
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.
-rwxr-xr-xadmin/merge-gnulib2
-rw-r--r--exec/configure.ac4
-rw-r--r--exec/exec.c77
-rw-r--r--lib/gnulib.mk.in12
-rw-r--r--lib/stpncpy.c92
-rw-r--r--m4/gnulib-comp.m410
-rw-r--r--m4/stpncpy.m4108
7 files changed, 8 insertions, 297 deletions
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index f64c0670bcf..2a713beb01a 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -45,7 +45,7 @@ GNULIB_MODULES='
45 pathmax pipe2 pselect pthread_sigmask 45 pathmax pipe2 pselect pthread_sigmask
46 qcopy-acl readlink readlinkat regex 46 qcopy-acl readlink readlinkat regex
47 sig2str sigdescr_np socklen stat-time std-gnu11 stdbool stdckdint stddef stdio 47 sig2str sigdescr_np socklen stat-time std-gnu11 stdbool stdckdint stddef stdio
48 stpcpy stpncpy strnlen strnlen strtoimax symlink sys_stat sys_time 48 stpcpy strnlen strnlen strtoimax symlink sys_stat sys_time
49 tempname time-h time_r time_rz timegm timer-time timespec-add timespec-sub 49 tempname time-h time_r time_rz timegm timer-time timespec-add timespec-sub
50 update-copyright unlocked-io utimensat 50 update-copyright unlocked-io utimensat
51 vla warnings year2038 51 vla warnings year2038
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
62AC_TYPE_PID_T 62AC_TYPE_PID_T
63 63
64AC_HEADER_STDBOOL 64AC_HEADER_STDBOOL
65AC_CHECK_FUNCS([getpagesize stpcpy stpncpy]) 65AC_CHECK_FUNCS([getpagesize stpcpy])
66AC_CHECK_DECLS([stpcpy, stpncpy]) 66AC_CHECK_DECLS([stpcpy])
67AC_CHECK_FUNC([process_vm_readv], 67AC_CHECK_FUNC([process_vm_readv],
68 [AC_CHECK_FUNC([process_vm_writev], 68 [AC_CHECK_FUNC([process_vm_writev],
69 [AC_CHECK_DECL([process_vm_readv], 69 [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)
66#define stpcpy rpl_stpcpy 66#define stpcpy rpl_stpcpy
67#endif /* !defined HAVE_STPCPY || !defined HAVE_DECL_STPCPY */ 67#endif /* !defined HAVE_STPCPY || !defined HAVE_DECL_STPCPY */
68 68
69#if !defined HAVE_STPNCPY || !defined HAVE_DECL_STPNCPY
70
71/* Copy no more than N bytes of SRC to DST, returning a pointer past
72 the last non-NUL byte written into DST. */
73
74static char *
75rpl_stpncpy (char *dest, const char *src, size_t n)
76{
77 char c, *s;
78 size_t n4;
79
80 s = dest;
81
82 if (n >= 4)
83 {
84 n4 = n >> 2;
85
86 for (;;)
87 {
88 c = *src++;
89 *dest++ = c;
90 if (c == '\0')
91 break;
92 c = *src++;
93 *dest++ = c;
94 if (c == '\0')
95 break;
96 c = *src++;
97 *dest++ = c;
98 if (c == '\0')
99 break;
100 c = *src++;
101 *dest++ = c;
102 if (c == '\0')
103 break;
104 if (--n4 == 0)
105 goto last_chars;
106 }
107 n -= dest - s;
108 goto zero_fill;
109 }
110
111 last_chars:
112 n &= 3;
113 if (n == 0)
114 return dest;
115
116 for (;;)
117 {
118 c = *src++;
119 --n;
120 *dest++ = c;
121 if (c == '\0')
122 break;
123 if (n == 0)
124 return dest;
125 }
126
127 zero_fill:
128 while (n-- > 0)
129 dest[n] = '\0';
130
131 return dest - 1;
132}
133
134#define stpncpy rpl_stpncpy
135#endif /* !defined HAVE_STPNCPY || !defined HAVE_DECL_STPNCPY */
136
137 69
138 70
139/* Executable reading functions. 71/* Executable reading functions.
@@ -1005,13 +937,14 @@ exec_0 (char *name, struct exec_tracee *tracee,
1005 else 937 else
1006 { 938 {
1007 /* If name is not absolute, then make it relative to TRACEE's 939 /* If name is not absolute, then make it relative to TRACEE's
1008 cwd. Use stpcpy, as sprintf is not reentrant. */ 940 cwd. Do not use sprintf at it is not reentrant and it
941 mishandles results longer than INT_MAX. */
1009 942
1010 if (name[0] && name[0] != '/') 943 if (name[0] && name[0] != '/')
1011 { 944 {
1012 /* Clear `buffer'. */ 945 /* Clear both buffers. */
1013 memset (buffer, 0, sizeof buffer); 946 memset (buffer, 0, sizeof buffer);
1014 memset (buffer1, 0, sizeof buffer); 947 memset (buffer1, 0, sizeof buffer1);
1015 948
1016 /* Copy over /proc, the PID, and /cwd/. */ 949 /* Copy over /proc, the PID, and /cwd/. */
1017 rewrite = stpcpy (buffer, "/proc/"); 950 rewrite = stpcpy (buffer, "/proc/");
@@ -1042,7 +975,7 @@ exec_0 (char *name, struct exec_tracee *tracee,
1042 975
1043 rewrite = buffer1 + link_size; 976 rewrite = buffer1 + link_size;
1044 remaining = buffer1 + sizeof buffer1 - rewrite - 1; 977 remaining = buffer1 + sizeof buffer1 - rewrite - 1;
1045 rewrite = stpncpy (rewrite, name, remaining); 978 memcpy (rewrite, name, strnlen (name, remaining));
1046 979
1047 /* Replace name with buffer1. */ 980 /* Replace name with buffer1. */
1048#ifndef REENTRANT 981#ifndef REENTRANT
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 78ecb544c6e..785bdc70c5c 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -157,7 +157,6 @@
157# stddef \ 157# stddef \
158# stdio \ 158# stdio \
159# stpcpy \ 159# stpcpy \
160# stpncpy \
161# strnlen \ 160# strnlen \
162# strtoimax \ 161# strtoimax \
163# symlink \ 162# symlink \
@@ -336,7 +335,6 @@ GL_COND_OBJ_SIGDESCR_NP_CONDITION = @GL_COND_OBJ_SIGDESCR_NP_CONDITION@
336GL_COND_OBJ_STDIO_READ_CONDITION = @GL_COND_OBJ_STDIO_READ_CONDITION@ 335GL_COND_OBJ_STDIO_READ_CONDITION = @GL_COND_OBJ_STDIO_READ_CONDITION@
337GL_COND_OBJ_STDIO_WRITE_CONDITION = @GL_COND_OBJ_STDIO_WRITE_CONDITION@ 336GL_COND_OBJ_STDIO_WRITE_CONDITION = @GL_COND_OBJ_STDIO_WRITE_CONDITION@
338GL_COND_OBJ_STPCPY_CONDITION = @GL_COND_OBJ_STPCPY_CONDITION@ 337GL_COND_OBJ_STPCPY_CONDITION = @GL_COND_OBJ_STPCPY_CONDITION@
339GL_COND_OBJ_STPNCPY_CONDITION = @GL_COND_OBJ_STPNCPY_CONDITION@
340GL_COND_OBJ_STRNLEN_CONDITION = @GL_COND_OBJ_STRNLEN_CONDITION@ 338GL_COND_OBJ_STRNLEN_CONDITION = @GL_COND_OBJ_STRNLEN_CONDITION@
341GL_COND_OBJ_STRTOIMAX_CONDITION = @GL_COND_OBJ_STRTOIMAX_CONDITION@ 339GL_COND_OBJ_STRTOIMAX_CONDITION = @GL_COND_OBJ_STRTOIMAX_CONDITION@
342GL_COND_OBJ_STRTOLL_CONDITION = @GL_COND_OBJ_STRTOLL_CONDITION@ 340GL_COND_OBJ_STRTOLL_CONDITION = @GL_COND_OBJ_STRTOLL_CONDITION@
@@ -3454,16 +3452,6 @@ endif
3454endif 3452endif
3455## end gnulib module stpcpy 3453## end gnulib module stpcpy
3456 3454
3457## begin gnulib module stpncpy
3458ifeq (,$(OMIT_GNULIB_MODULE_stpncpy))
3459
3460ifneq (,$(GL_COND_OBJ_STPNCPY_CONDITION))
3461libgnu_a_SOURCES += stpncpy.c
3462endif
3463
3464endif
3465## end gnulib module stpncpy
3466
3467## begin gnulib module string 3455## begin gnulib module string
3468ifeq (,$(OMIT_GNULIB_MODULE_string)) 3456ifeq (,$(OMIT_GNULIB_MODULE_string))
3469 3457
diff --git a/lib/stpncpy.c b/lib/stpncpy.c
deleted file mode 100644
index d1422a927df..00000000000
--- a/lib/stpncpy.c
+++ /dev/null
@@ -1,92 +0,0 @@
1/* Copyright (C) 1993, 1995-1997, 2002-2003, 2005-2007, 2009-2023 Free Software
2 * Foundation, Inc.
3
4 NOTE: The canonical source of this file is maintained with the GNU C Library.
5 Bugs can be reported to bug-glibc@gnu.org.
6
7 This file is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
11
12 This file is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with this program. If not, see <https://www.gnu.org/licenses/>. */
19
20/* This is almost copied from strncpy.c, written by Torbjorn Granlund. */
21
22#include <config.h>
23
24/* Specification. */
25#include <string.h>
26
27#ifndef weak_alias
28# define __stpncpy stpncpy
29#endif
30
31/* Copy no more than N bytes of SRC to DST, returning a pointer past the
32 last non-NUL byte written into DST. */
33char *
34(__stpncpy) (char *dest, const char *src, size_t n)
35{
36 char c;
37 char *s = dest;
38
39 if (n >= 4)
40 {
41 size_t n4 = n >> 2;
42
43 for (;;)
44 {
45 c = *src++;
46 *dest++ = c;
47 if (c == '\0')
48 break;
49 c = *src++;
50 *dest++ = c;
51 if (c == '\0')
52 break;
53 c = *src++;
54 *dest++ = c;
55 if (c == '\0')
56 break;
57 c = *src++;
58 *dest++ = c;
59 if (c == '\0')
60 break;
61 if (--n4 == 0)
62 goto last_chars;
63 }
64 n -= dest - s;
65 goto zero_fill;
66 }
67
68 last_chars:
69 n &= 3;
70 if (n == 0)
71 return dest;
72
73 for (;;)
74 {
75 c = *src++;
76 --n;
77 *dest++ = c;
78 if (c == '\0')
79 break;
80 if (n == 0)
81 return dest;
82 }
83
84 zero_fill:
85 while (n-- > 0)
86 dest[n] = '\0';
87
88 return dest - 1;
89}
90#ifdef weak_alias
91weak_alias (__stpncpy, stpncpy)
92#endif
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 72adcf90d5e..3382e9bc241 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -181,7 +181,6 @@ AC_DEFUN([gl_EARLY],
181 gl_STDIO_H_EARLY 181 gl_STDIO_H_EARLY
182 # Code from module stdlib: 182 # Code from module stdlib:
183 # Code from module stpcpy: 183 # Code from module stpcpy:
184 # Code from module stpncpy:
185 # Code from module string: 184 # Code from module string:
186 # Code from module strnlen: 185 # Code from module strnlen:
187 # Code from module strtoimax: 186 # Code from module strtoimax:
@@ -567,13 +566,6 @@ AC_DEFUN([gl_INIT],
567 gl_PREREQ_STPCPY 566 gl_PREREQ_STPCPY
568 ]) 567 ])
569 gl_STRING_MODULE_INDICATOR([stpcpy]) 568 gl_STRING_MODULE_INDICATOR([stpcpy])
570 gl_FUNC_STPNCPY
571 gl_CONDITIONAL([GL_COND_OBJ_STPNCPY],
572 [test $HAVE_STPNCPY = 0 || test $REPLACE_STPNCPY = 1])
573 AM_COND_IF([GL_COND_OBJ_STPNCPY], [
574 gl_PREREQ_STPNCPY
575 ])
576 gl_STRING_MODULE_INDICATOR([stpncpy])
577 gl_STRING_H 569 gl_STRING_H
578 gl_STRING_H_REQUIRE_DEFAULTS 570 gl_STRING_H_REQUIRE_DEFAULTS
579 AC_PROG_MKDIR_P 571 AC_PROG_MKDIR_P
@@ -1422,7 +1414,6 @@ AC_DEFUN([gl_FILE_LIST], [
1422 lib/stdio.in.h 1414 lib/stdio.in.h
1423 lib/stdlib.in.h 1415 lib/stdlib.in.h
1424 lib/stpcpy.c 1416 lib/stpcpy.c
1425 lib/stpncpy.c
1426 lib/str-two-way.h 1417 lib/str-two-way.h
1427 lib/strftime.h 1418 lib/strftime.h
1428 lib/string.in.h 1419 lib/string.in.h
@@ -1569,7 +1560,6 @@ AC_DEFUN([gl_FILE_LIST], [
1569 m4/stdio_h.m4 1560 m4/stdio_h.m4
1570 m4/stdlib_h.m4 1561 m4/stdlib_h.m4
1571 m4/stpcpy.m4 1562 m4/stpcpy.m4
1572 m4/stpncpy.m4
1573 m4/string_h.m4 1563 m4/string_h.m4
1574 m4/strnlen.m4 1564 m4/strnlen.m4
1575 m4/strtoimax.m4 1565 m4/strtoimax.m4
diff --git a/m4/stpncpy.m4 b/m4/stpncpy.m4
deleted file mode 100644
index 073607004be..00000000000
--- a/m4/stpncpy.m4
+++ /dev/null
@@ -1,108 +0,0 @@
1# stpncpy.m4 serial 22
2dnl Copyright (C) 2002-2003, 2005-2007, 2009-2023 Free Software Foundation,
3dnl Inc.
4dnl This file is free software; the Free Software Foundation
5dnl gives unlimited permission to copy and/or distribute it,
6dnl with or without modifications, as long as this notice is preserved.
7
8AC_DEFUN([gl_FUNC_STPNCPY],
9[
10 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
11
12 dnl Persuade glibc <string.h> to declare stpncpy().
13 AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
14
15 dnl The stpncpy() declaration in lib/string.in.h uses 'restrict'.
16 AC_REQUIRE([AC_C_RESTRICT])
17
18 AC_REQUIRE([gl_STRING_H_DEFAULTS])
19
20 dnl Both glibc and AIX (4.3.3, 5.1) have an stpncpy() function
21 dnl declared in <string.h>. Its side effects are the same as those
22 dnl of strncpy():
23 dnl stpncpy (dest, src, n)
24 dnl overwrites dest[0..n-1], min(strlen(src),n) bytes coming from src,
25 dnl and the remaining bytes being NULs. However, the return value is
26 dnl in glibc: dest + min(strlen(src),n)
27 dnl in AIX: dest + max(0,n-1)
28 dnl Only the glibc return value is useful in practice.
29
30 AC_CHECK_DECLS_ONCE([stpncpy])
31 gl_CHECK_FUNCS_ANDROID([stpncpy], [[#include <string.h>]])
32 if test $ac_cv_func_stpncpy = yes; then
33 AC_CACHE_CHECK([for working stpncpy], [gl_cv_func_stpncpy], [
34 AC_RUN_IFELSE(
35 [AC_LANG_SOURCE([[
36#include <stdlib.h>
37#include <string.h> /* for strcpy */
38/* The stpncpy prototype is missing in <string.h> on AIX 4. */
39#if !HAVE_DECL_STPNCPY
40extern
41# ifdef __cplusplus
42"C"
43# endif
44char *stpncpy (char *dest, const char *src, size_t n);
45#endif
46int main ()
47{
48 int result = 0;
49 const char *src = "Hello";
50 char dest[10];
51 /* AIX 4.3.3 and AIX 5.1 stpncpy() returns dest+1 here. */
52 {
53 strcpy (dest, "\377\377\377\377\377\377");
54 if (stpncpy (dest, src, 2) != dest + 2)
55 result |= 1;
56 }
57 /* AIX 4.3.3 and AIX 5.1 stpncpy() returns dest+4 here. */
58 {
59 strcpy (dest, "\377\377\377\377\377\377");
60 if (stpncpy (dest, src, 5) != dest + 5)
61 result |= 2;
62 }
63 /* AIX 4.3.3 and AIX 5.1 stpncpy() returns dest+6 here. */
64 {
65 strcpy (dest, "\377\377\377\377\377\377");
66 if (stpncpy (dest, src, 7) != dest + 5)
67 result |= 4;
68 }
69 return result;
70}
71]])],
72 [gl_cv_func_stpncpy=yes],
73 [gl_cv_func_stpncpy=no],
74 [dnl Guess yes on glibc systems and musl systems.
75 AC_EGREP_CPP([Thanks for using GNU], [
76#include <features.h>
77#ifdef __GNU_LIBRARY__
78 Thanks for using GNU
79#endif
80], [gl_cv_func_stpncpy="guessing yes"],
81 [case "$host_os" in
82 *-musl* | midipix*) gl_cv_func_stpncpy="guessing yes" ;;
83 *) gl_cv_func_stpncpy="$gl_cross_guess_normal" ;;
84 esac
85 ])
86 ])
87 ])
88 case "$gl_cv_func_stpncpy" in
89 *yes)
90 AC_DEFINE([HAVE_STPNCPY], [1],
91 [Define if you have the stpncpy() function and it works.])
92 ;;
93 *)
94 REPLACE_STPNCPY=1
95 ;;
96 esac
97 else
98 HAVE_STPNCPY=0
99 case "$gl_cv_onwards_func_stpncpy" in
100 future*) REPLACE_STPNCPY=1 ;;
101 esac
102 fi
103])
104
105# Prerequisites of lib/stpncpy.c.
106AC_DEFUN([gl_PREREQ_STPNCPY], [
107 :
108])