diff options
| author | Paul Eggert | 2019-06-25 14:53:39 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-06-25 14:55:08 -0700 |
| commit | d7c6836288c91bb639956cb8c748dd6597c55cd4 (patch) | |
| tree | 687f6f257d3cb5f4bd54eb634aef2737eb9c0856 | |
| parent | 349b778dde7f583a92dd1531aef3ff5c336e9aee (diff) | |
| download | emacs-d7c6836288c91bb639956cb8c748dd6597c55cd4.tar.gz emacs-d7c6836288c91bb639956cb8c748dd6597c55cd4.zip | |
Avoid some strlen work, primarily via strnlen
* admin/merge-gnulib (GNULIB_MODULES): Add strnlen.
* lib-src/etags.c (find_entries):
* src/emacs.c (main):
* src/nsmenu.m (parseKeyEquiv:):
* src/nsterm.m (ns_xlfd_to_fontname):
* src/term.c (vfatal):
Prefer !*X to !strlen (X).
* lib-src/etags.c (pfnote, add_regex):
* lib-src/pop.c (pop_open):
* lib-src/update-game-score.c (main):
* lwlib/lwlib.c (lw_separator_p):
* src/doprnt.c (doprnt):
* src/emacs.c (main):
* src/inotify.c (inotifyevent_to_event):
* src/keyboard.c (menu_separator_name_p, parse_tool_bar_item):
* src/sysdep.c (get_current_dir_name_or_unreachable):
* src/xdisp.c (store_mode_line_string):
Use strnlen to avoid unnecessary work with strlen.
* lib-src/etags.c (Prolog_functions, prolog_pr)
(Erlang_functions, erlang_func):
Prefer ptrdiff_t to size_t when either will do.
(prolog_pr, erlang_func): New arg LASTLEN, to avoid
unnecessary strlen call. All callers changed.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* lib/strnlen.c, m4/strnlen.m4: New files, copied from Gnulib.
* lwlib/lwlib.c (lw_separator_p):
* src/json.c (json_has_prefix):
Use strncmp to avoid unecessary work with strlen + memcmp.
* src/process.c (set_socket_option): Use SBYTES instead of strlen.
| -rwxr-xr-x | admin/merge-gnulib | 2 | ||||
| -rw-r--r-- | lib-src/etags.c | 155 | ||||
| -rw-r--r-- | lib-src/pop.c | 4 | ||||
| -rw-r--r-- | lib-src/update-game-score.c | 2 | ||||
| -rw-r--r-- | lib/gnulib.mk.in | 14 | ||||
| -rw-r--r-- | lib/strnlen.c | 30 | ||||
| -rw-r--r-- | lwlib/lwlib.c | 5 | ||||
| -rw-r--r-- | m4/gnulib-comp.m4 | 9 | ||||
| -rw-r--r-- | m4/strnlen.m4 | 30 | ||||
| -rw-r--r-- | src/doprnt.c | 4 | ||||
| -rw-r--r-- | src/emacs.c | 4 | ||||
| -rw-r--r-- | src/inotify.c | 3 | ||||
| -rw-r--r-- | src/json.c | 4 | ||||
| -rw-r--r-- | src/keyboard.c | 15 | ||||
| -rw-r--r-- | src/nsmenu.m | 2 | ||||
| -rw-r--r-- | src/nsterm.m | 2 | ||||
| -rw-r--r-- | src/process.c | 6 | ||||
| -rw-r--r-- | src/sysdep.c | 4 | ||||
| -rw-r--r-- | src/term.c | 2 | ||||
| -rw-r--r-- | src/xdisp.c | 4 |
20 files changed, 174 insertions, 127 deletions
diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 78e74882f3d..6cf29589f71 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib | |||
| @@ -40,7 +40,7 @@ GNULIB_MODULES=' | |||
| 40 | manywarnings memmem-simple memrchr minmax mkostemp mktime nstrftime | 40 | manywarnings memmem-simple memrchr minmax mkostemp mktime nstrftime |
| 41 | pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat regex | 41 | pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat regex |
| 42 | sig2str socklen stat-time std-gnu11 stdalign stddef stdio | 42 | sig2str socklen stat-time std-gnu11 stdalign stddef stdio |
| 43 | stpcpy strtoimax symlink sys_stat sys_time | 43 | stpcpy strnlen strtoimax symlink sys_stat sys_time |
| 44 | tempname time time_r time_rz timegm timer-time timespec-add timespec-sub | 44 | tempname time time_r time_rz timegm timer-time timespec-add timespec-sub |
| 45 | update-copyright unlocked-io utimens | 45 | update-copyright unlocked-io utimens |
| 46 | vla warnings | 46 | vla warnings |
diff --git a/lib-src/etags.c b/lib-src/etags.c index 442b622cceb..036c485d0bb 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c | |||
| @@ -1811,7 +1811,7 @@ find_entries (FILE *inf) | |||
| 1811 | } | 1811 | } |
| 1812 | *cp = '\0'; | 1812 | *cp = '\0'; |
| 1813 | 1813 | ||
| 1814 | if (strlen (lp) > 0) | 1814 | if (*lp) |
| 1815 | { | 1815 | { |
| 1816 | lang = get_language_from_interpreter (lp); | 1816 | lang = get_language_from_interpreter (lp); |
| 1817 | if (lang != NULL && lang->function != NULL) | 1817 | if (lang != NULL && lang->function != NULL) |
| @@ -2012,7 +2012,7 @@ pfnote (char *name, bool is_func, char *linestart, int linelen, int lno, | |||
| 2012 | np->left = np->right = NULL; | 2012 | np->left = np->right = NULL; |
| 2013 | if (CTAGS && !cxref_style) | 2013 | if (CTAGS && !cxref_style) |
| 2014 | { | 2014 | { |
| 2015 | if (strlen (linestart) < 50) | 2015 | if (strnlen (linestart, 50) < 50) |
| 2016 | np->regex = concat (linestart, "$", ""); | 2016 | np->regex = concat (linestart, "$", ""); |
| 2017 | else | 2017 | else |
| 2018 | np->regex = savenstr (linestart, 50); | 2018 | np->regex = savenstr (linestart, 50); |
| @@ -5883,20 +5883,15 @@ HTML_labels (FILE *inf) | |||
| 5883 | * Original code by Sunichirou Sugou (1989) | 5883 | * Original code by Sunichirou Sugou (1989) |
| 5884 | * Rewritten by Anders Lindgren (1996) | 5884 | * Rewritten by Anders Lindgren (1996) |
| 5885 | */ | 5885 | */ |
| 5886 | static size_t prolog_pr (char *, char *); | 5886 | static ptrdiff_t prolog_pr (char *, char *, ptrdiff_t); |
| 5887 | static void prolog_skip_comment (linebuffer *, FILE *); | 5887 | static void prolog_skip_comment (linebuffer *, FILE *); |
| 5888 | static size_t prolog_atom (char *, size_t); | 5888 | static size_t prolog_atom (char *, size_t); |
| 5889 | 5889 | ||
| 5890 | static void | 5890 | static void |
| 5891 | Prolog_functions (FILE *inf) | 5891 | Prolog_functions (FILE *inf) |
| 5892 | { | 5892 | { |
| 5893 | char *cp, *last; | 5893 | char *cp, *last = NULL; |
| 5894 | size_t len; | 5894 | ptrdiff_t lastlen = 0, allocated = 0; |
| 5895 | size_t allocated; | ||
| 5896 | |||
| 5897 | allocated = 0; | ||
| 5898 | len = 0; | ||
| 5899 | last = NULL; | ||
| 5900 | 5895 | ||
| 5901 | LOOP_ON_INPUT_LINES (inf, lb, cp) | 5896 | LOOP_ON_INPUT_LINES (inf, lb, cp) |
| 5902 | { | 5897 | { |
| @@ -5906,17 +5901,22 @@ Prolog_functions (FILE *inf) | |||
| 5906 | continue; | 5901 | continue; |
| 5907 | else if (cp[0] == '/' && cp[1] == '*') /* comment. */ | 5902 | else if (cp[0] == '/' && cp[1] == '*') /* comment. */ |
| 5908 | prolog_skip_comment (&lb, inf); | 5903 | prolog_skip_comment (&lb, inf); |
| 5909 | else if ((len = prolog_pr (cp, last)) > 0) | 5904 | else |
| 5910 | { | 5905 | { |
| 5911 | /* Predicate or rule. Store the function name so that we | 5906 | ptrdiff_t len = prolog_pr (cp, last, lastlen); |
| 5912 | only generate a tag for the first clause. */ | 5907 | if (0 < len) |
| 5913 | if (last == NULL) | 5908 | { |
| 5914 | last = xnew (len + 1, char); | 5909 | /* Store the predicate name to avoid generating duplicate |
| 5915 | else if (len + 1 > allocated) | 5910 | tags later. */ |
| 5916 | xrnew (last, len + 1, char); | 5911 | if (allocated <= len) |
| 5917 | allocated = len + 1; | 5912 | { |
| 5918 | memcpy (last, cp, len); | 5913 | xrnew (last, len + 1, char); |
| 5919 | last[len] = '\0'; | 5914 | allocated = len + 1; |
| 5915 | } | ||
| 5916 | memcpy (last, cp, len); | ||
| 5917 | last[len] = '\0'; | ||
| 5918 | lastlen = len; | ||
| 5919 | } | ||
| 5920 | } | 5920 | } |
| 5921 | } | 5921 | } |
| 5922 | free (last); | 5922 | free (last); |
| @@ -5949,33 +5949,25 @@ prolog_skip_comment (linebuffer *plb, FILE *inf) | |||
| 5949 | * Return the size of the name of the predicate or rule, or 0 if no | 5949 | * Return the size of the name of the predicate or rule, or 0 if no |
| 5950 | * header was found. | 5950 | * header was found. |
| 5951 | */ | 5951 | */ |
| 5952 | static size_t | 5952 | static ptrdiff_t |
| 5953 | prolog_pr (char *s, char *last) | 5953 | prolog_pr (char *s, char *last, ptrdiff_t lastlen) |
| 5954 | |||
| 5955 | /* Name of last clause. */ | ||
| 5956 | { | 5954 | { |
| 5957 | size_t pos; | 5955 | ptrdiff_t len = prolog_atom (s, 0); |
| 5958 | size_t len; | 5956 | if (len == 0) |
| 5959 | |||
| 5960 | pos = prolog_atom (s, 0); | ||
| 5961 | if (! pos) | ||
| 5962 | return 0; | 5957 | return 0; |
| 5958 | ptrdiff_t pos = skip_spaces (s + len) - s; | ||
| 5963 | 5959 | ||
| 5964 | len = pos; | 5960 | /* Save only the first clause. */ |
| 5965 | pos = skip_spaces (s + pos) - s; | ||
| 5966 | |||
| 5967 | if ((s[pos] == '.' | 5961 | if ((s[pos] == '.' |
| 5968 | || (s[pos] == '(' && (pos += 1)) | 5962 | || (s[pos] == '(' && (pos += 1)) |
| 5969 | || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2))) | 5963 | || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2))) |
| 5970 | && (last == NULL /* save only the first clause */ | 5964 | && ! (lastlen == len && memcmp (s, last, len) == 0)) |
| 5971 | || len != strlen (last) | 5965 | { |
| 5972 | || !strneq (s, last, len))) | 5966 | make_tag (s, len, true, s, pos, lineno, linecharno); |
| 5973 | { | 5967 | return len; |
| 5974 | make_tag (s, len, true, s, pos, lineno, linecharno); | 5968 | } |
| 5975 | return len; | 5969 | |
| 5976 | } | 5970 | return 0; |
| 5977 | else | ||
| 5978 | return 0; | ||
| 5979 | } | 5971 | } |
| 5980 | 5972 | ||
| 5981 | /* | 5973 | /* |
| @@ -6043,21 +6035,15 @@ prolog_atom (char *s, size_t pos) | |||
| 6043 | * Assumes that Erlang functions start at column 0. | 6035 | * Assumes that Erlang functions start at column 0. |
| 6044 | * Original code by Anders Lindgren (1996) | 6036 | * Original code by Anders Lindgren (1996) |
| 6045 | */ | 6037 | */ |
| 6046 | static int erlang_func (char *, char *, int *); | 6038 | static int erlang_func (char *, char *, ptrdiff_t, ptrdiff_t *); |
| 6047 | static void erlang_attribute (char *); | 6039 | static void erlang_attribute (char *); |
| 6048 | static int erlang_atom (char *); | 6040 | static int erlang_atom (char *); |
| 6049 | 6041 | ||
| 6050 | static void | 6042 | static void |
| 6051 | Erlang_functions (FILE *inf) | 6043 | Erlang_functions (FILE *inf) |
| 6052 | { | 6044 | { |
| 6053 | char *cp, *last; | 6045 | char *cp, *last = NULL; |
| 6054 | int len; | 6046 | ptrdiff_t lastlen = 0, allocated = 0; |
| 6055 | int allocated; | ||
| 6056 | int name_offset = 0; | ||
| 6057 | |||
| 6058 | allocated = 0; | ||
| 6059 | len = 0; | ||
| 6060 | last = NULL; | ||
| 6061 | 6047 | ||
| 6062 | LOOP_ON_INPUT_LINES (inf, lb, cp) | 6048 | LOOP_ON_INPUT_LINES (inf, lb, cp) |
| 6063 | { | 6049 | { |
| @@ -6078,19 +6064,23 @@ Erlang_functions (FILE *inf) | |||
| 6078 | last = NULL; | 6064 | last = NULL; |
| 6079 | } | 6065 | } |
| 6080 | } | 6066 | } |
| 6081 | else if ((len = erlang_func (cp, last, &name_offset)) > 0) | 6067 | else |
| 6082 | { | 6068 | { |
| 6083 | /* | 6069 | ptrdiff_t name_offset; |
| 6084 | * Function. Store the function name so that we only | 6070 | ptrdiff_t len = erlang_func (cp, last, lastlen, &name_offset); |
| 6085 | * generates a tag for the first clause. | 6071 | if (0 < len) |
| 6086 | */ | 6072 | { |
| 6087 | if (last == NULL) | 6073 | /* Store the function name to avoid generating duplicate |
| 6088 | last = xnew (len + 1, char); | 6074 | tags later. */ |
| 6089 | else if (len + 1 > allocated) | 6075 | if (allocated <= len) |
| 6090 | xrnew (last, len + 1, char); | 6076 | { |
| 6091 | allocated = len + 1; | 6077 | xrnew (last, len + 1, char); |
| 6092 | memcpy (last, cp + name_offset, len); | 6078 | allocated = len + 1; |
| 6093 | last[len] = '\0'; | 6079 | } |
| 6080 | memcpy (last, cp + name_offset, len); | ||
| 6081 | last[len] = '\0'; | ||
| 6082 | lastlen = len; | ||
| 6083 | } | ||
| 6094 | } | 6084 | } |
| 6095 | } | 6085 | } |
| 6096 | free (last); | 6086 | free (last); |
| @@ -6108,40 +6098,27 @@ Erlang_functions (FILE *inf) | |||
| 6108 | * was found. | 6098 | * was found. |
| 6109 | */ | 6099 | */ |
| 6110 | static int | 6100 | static int |
| 6111 | erlang_func (char *s, char *last, int *name_offset) | 6101 | erlang_func (char *s, char *last, ptrdiff_t lastlen, ptrdiff_t *name_offset) |
| 6112 | |||
| 6113 | /* Name of last clause. */ | ||
| 6114 | { | 6102 | { |
| 6115 | int pos; | ||
| 6116 | int len; | ||
| 6117 | char *name = s; | 6103 | char *name = s; |
| 6118 | 6104 | ptrdiff_t len = erlang_atom (s); | |
| 6119 | pos = erlang_atom (s); | 6105 | if (len == 0) |
| 6120 | if (pos < 1) | ||
| 6121 | return 0; | 6106 | return 0; |
| 6122 | 6107 | ptrdiff_t pos = skip_spaces (s + len) - s; | |
| 6123 | len = pos; | ||
| 6124 | pos = skip_spaces (s + pos) - s; | ||
| 6125 | 6108 | ||
| 6126 | /* If the name is quoted, the quotes are not part of the name. */ | 6109 | /* If the name is quoted, the quotes are not part of the name. */ |
| 6127 | if (len > 2 && name[0] == '\'' && name[len - 1] == '\'') | 6110 | bool quoted = 2 < len && name[0] == '\'' && name[len - 1] == '\''; |
| 6128 | { | 6111 | name += quoted; |
| 6129 | *name_offset = 1; | 6112 | len -= 2 * quoted; |
| 6130 | name++; | ||
| 6131 | len -= 2; | ||
| 6132 | } | ||
| 6133 | else | ||
| 6134 | *name_offset = 0; | ||
| 6135 | 6113 | ||
| 6136 | /* Save only the first clause. */ | 6114 | /* Save only the first clause. */ |
| 6137 | if (s[pos++] == '(' | 6115 | if (s[pos++] == '(' |
| 6138 | && (last == NULL | 6116 | && ! (lastlen == len && memcmp (name, last, len) == 0)) |
| 6139 | || len != (int)strlen (last) | 6117 | { |
| 6140 | || !strneq (name, last, len))) | 6118 | make_tag (s, len, true, s, pos, lineno, linecharno); |
| 6141 | { | 6119 | *name_offset = quoted; |
| 6142 | make_tag (name, len, true, s, pos, lineno, linecharno); | 6120 | return len; |
| 6143 | return len; | 6121 | } |
| 6144 | } | ||
| 6145 | 6122 | ||
| 6146 | return 0; | 6123 | return 0; |
| 6147 | } | 6124 | } |
| @@ -6363,7 +6340,7 @@ add_regex (char *regexp_pattern, language *lang) | |||
| 6363 | single_line = false; /* dot does not match newline */ | 6340 | single_line = false; /* dot does not match newline */ |
| 6364 | 6341 | ||
| 6365 | 6342 | ||
| 6366 | if (strlen (regexp_pattern) < 3) | 6343 | if (strnlen (regexp_pattern, 3) < 3) |
| 6367 | { | 6344 | { |
| 6368 | error ("null regexp"); | 6345 | error ("null regexp"); |
| 6369 | return; | 6346 | return; |
diff --git a/lib-src/pop.c b/lib-src/pop.c index c14808d6d37..e4bd6c04965 100644 --- a/lib-src/pop.c +++ b/lib-src/pop.c | |||
| @@ -285,7 +285,7 @@ pop_open (char *host, char *username, char *password, int flags) | |||
| 285 | /* | 285 | /* |
| 286 | * I really shouldn't use the pop_error variable like this, but.... | 286 | * I really shouldn't use the pop_error variable like this, but.... |
| 287 | */ | 287 | */ |
| 288 | if (strlen (username) > ERROR_MAX - 6) | 288 | if (strnlen (username, ERROR_MAX - 6 + 1) == ERROR_MAX - 6 + 1) |
| 289 | { | 289 | { |
| 290 | pop_close (server); | 290 | pop_close (server); |
| 291 | strcpy (pop_error, | 291 | strcpy (pop_error, |
| @@ -299,7 +299,7 @@ pop_open (char *host, char *username, char *password, int flags) | |||
| 299 | return (0); | 299 | return (0); |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | if (strlen (password) > ERROR_MAX - 6) | 302 | if (strnlen (password, ERROR_MAX - 6 + 1) == ERROR_MAX - 6 + 1) |
| 303 | { | 303 | { |
| 304 | pop_close (server); | 304 | pop_close (server); |
| 305 | strcpy (pop_error, | 305 | strcpy (pop_error, |
diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c index 8a6f46b38e7..782425186e8 100644 --- a/lib-src/update-game-score.c +++ b/lib-src/update-game-score.c | |||
| @@ -240,7 +240,7 @@ main (int argc, char **argv) | |||
| 240 | if (! user) | 240 | if (! user) |
| 241 | lose_syserr ("Couldn't determine user id"); | 241 | lose_syserr ("Couldn't determine user id"); |
| 242 | data = argv[optind + 2]; | 242 | data = argv[optind + 2]; |
| 243 | if (strlen (data) > MAX_DATA_LEN) | 243 | if (strnlen (data, MAX_DATA_LEN + 1) == MAX_DATA_LEN + 1) |
| 244 | data[MAX_DATA_LEN] = '\0'; | 244 | data[MAX_DATA_LEN] = '\0'; |
| 245 | nl = strchr (data, '\n'); | 245 | nl = strchr (data, '\n'); |
| 246 | if (nl) | 246 | if (nl) |
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index b9a32d9dbc1..b4d510bd62e 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in | |||
| @@ -136,6 +136,7 @@ | |||
| 136 | # stddef \ | 136 | # stddef \ |
| 137 | # stdio \ | 137 | # stdio \ |
| 138 | # stpcpy \ | 138 | # stpcpy \ |
| 139 | # strnlen \ | ||
| 139 | # strtoimax \ | 140 | # strtoimax \ |
| 140 | # symlink \ | 141 | # symlink \ |
| 141 | # sys_stat \ | 142 | # sys_stat \ |
| @@ -1075,7 +1076,6 @@ gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@ | |||
| 1075 | gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ | 1076 | gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ |
| 1076 | gl_GNULIB_ENABLED_malloca = @gl_GNULIB_ENABLED_malloca@ | 1077 | gl_GNULIB_ENABLED_malloca = @gl_GNULIB_ENABLED_malloca@ |
| 1077 | gl_GNULIB_ENABLED_open = @gl_GNULIB_ENABLED_open@ | 1078 | gl_GNULIB_ENABLED_open = @gl_GNULIB_ENABLED_open@ |
| 1078 | gl_GNULIB_ENABLED_pathmax = @gl_GNULIB_ENABLED_pathmax@ | ||
| 1079 | gl_GNULIB_ENABLED_strtoll = @gl_GNULIB_ENABLED_strtoll@ | 1079 | gl_GNULIB_ENABLED_strtoll = @gl_GNULIB_ENABLED_strtoll@ |
| 1080 | gl_LIBOBJS = @gl_LIBOBJS@ | 1080 | gl_LIBOBJS = @gl_LIBOBJS@ |
| 1081 | gl_LTLIBOBJS = @gl_LTLIBOBJS@ | 1081 | gl_LTLIBOBJS = @gl_LTLIBOBJS@ |
| @@ -1110,7 +1110,6 @@ pdfdir = @pdfdir@ | |||
| 1110 | prefix = @prefix@ | 1110 | prefix = @prefix@ |
| 1111 | program_transform_name = @program_transform_name@ | 1111 | program_transform_name = @program_transform_name@ |
| 1112 | psdir = @psdir@ | 1112 | psdir = @psdir@ |
| 1113 | runstatedir = @runstatedir@ | ||
| 1114 | sbindir = @sbindir@ | 1113 | sbindir = @sbindir@ |
| 1115 | sharedstatedir = @sharedstatedir@ | 1114 | sharedstatedir = @sharedstatedir@ |
| 1116 | srcdir = @srcdir@ | 1115 | srcdir = @srcdir@ |
| @@ -2811,6 +2810,17 @@ EXTRA_DIST += string.in.h | |||
| 2811 | endif | 2810 | endif |
| 2812 | ## end gnulib module string | 2811 | ## end gnulib module string |
| 2813 | 2812 | ||
| 2813 | ## begin gnulib module strnlen | ||
| 2814 | ifeq (,$(OMIT_GNULIB_MODULE_strnlen)) | ||
| 2815 | |||
| 2816 | |||
| 2817 | EXTRA_DIST += strnlen.c | ||
| 2818 | |||
| 2819 | EXTRA_libgnu_a_SOURCES += strnlen.c | ||
| 2820 | |||
| 2821 | endif | ||
| 2822 | ## end gnulib module strnlen | ||
| 2823 | |||
| 2814 | ## begin gnulib module strtoimax | 2824 | ## begin gnulib module strtoimax |
| 2815 | ifeq (,$(OMIT_GNULIB_MODULE_strtoimax)) | 2825 | ifeq (,$(OMIT_GNULIB_MODULE_strtoimax)) |
| 2816 | 2826 | ||
diff --git a/lib/strnlen.c b/lib/strnlen.c new file mode 100644 index 00000000000..9fb663509a0 --- /dev/null +++ b/lib/strnlen.c | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* Find the length of STRING, but scan at most MAXLEN characters. | ||
| 2 | Copyright (C) 2005-2007, 2009-2019 Free Software Foundation, Inc. | ||
| 3 | Written by Simon Josefsson. | ||
| 4 | |||
| 5 | This program is free software; you can redistribute it and/or modify | ||
| 6 | it under the terms of the GNU General Public License as published by | ||
| 7 | the Free Software Foundation; either version 3, or (at your option) | ||
| 8 | any later version. | ||
| 9 | |||
| 10 | This program is distributed in the hope that it will be useful, | ||
| 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | GNU General Public License for more details. | ||
| 14 | |||
| 15 | You should have received a copy of the GNU General Public License | ||
| 16 | along with this program; if not, see <https://www.gnu.org/licenses/>. */ | ||
| 17 | |||
| 18 | #include <config.h> | ||
| 19 | |||
| 20 | #include <string.h> | ||
| 21 | |||
| 22 | /* Find the length of STRING, but scan at most MAXLEN characters. | ||
| 23 | If no '\0' terminator is found in that many characters, return MAXLEN. */ | ||
| 24 | |||
| 25 | size_t | ||
| 26 | strnlen (const char *string, size_t maxlen) | ||
| 27 | { | ||
| 28 | const char *end = memchr (string, '\0', maxlen); | ||
| 29 | return end ? (size_t) (end - string) : maxlen; | ||
| 30 | } | ||
diff --git a/lwlib/lwlib.c b/lwlib/lwlib.c index 8142d92f077..f37c1058792 100644 --- a/lwlib/lwlib.c +++ b/lwlib/lwlib.c | |||
| @@ -1233,8 +1233,7 @@ lw_separator_p (const char *label, enum menu_separator *type, int motif_p) | |||
| 1233 | { | 1233 | { |
| 1234 | int separator_p = 0; | 1234 | int separator_p = 0; |
| 1235 | 1235 | ||
| 1236 | if (strlen (label) >= 3 | 1236 | if (strncmp (label, "--:", 3) == 0) |
| 1237 | && memcmp (label, "--:", 3) == 0) | ||
| 1238 | { | 1237 | { |
| 1239 | static struct separator_table | 1238 | static struct separator_table |
| 1240 | { | 1239 | { |
| @@ -1276,7 +1275,7 @@ lw_separator_p (const char *label, enum menu_separator *type, int motif_p) | |||
| 1276 | break; | 1275 | break; |
| 1277 | } | 1276 | } |
| 1278 | } | 1277 | } |
| 1279 | else if (strlen (label) > 3 | 1278 | else if (strnlen (label, 4) == 4 |
| 1280 | && memcmp (label, "--", 2) == 0 | 1279 | && memcmp (label, "--", 2) == 0 |
| 1281 | && label[2] != '-') | 1280 | && label[2] != '-') |
| 1282 | { | 1281 | { |
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index cb6dce15ccf..7e724fe3c4e 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 | |||
| @@ -154,6 +154,7 @@ AC_DEFUN([gl_EARLY], | |||
| 154 | # Code from module stdlib: | 154 | # Code from module stdlib: |
| 155 | # Code from module stpcpy: | 155 | # Code from module stpcpy: |
| 156 | # Code from module string: | 156 | # Code from module string: |
| 157 | # Code from module strnlen: | ||
| 157 | # Code from module strtoimax: | 158 | # Code from module strtoimax: |
| 158 | # Code from module strtoll: | 159 | # Code from module strtoll: |
| 159 | # Code from module symlink: | 160 | # Code from module symlink: |
| @@ -403,6 +404,12 @@ AC_DEFUN([gl_INIT], | |||
| 403 | fi | 404 | fi |
| 404 | gl_STRING_MODULE_INDICATOR([stpcpy]) | 405 | gl_STRING_MODULE_INDICATOR([stpcpy]) |
| 405 | gl_HEADER_STRING_H | 406 | gl_HEADER_STRING_H |
| 407 | gl_FUNC_STRNLEN | ||
| 408 | if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then | ||
| 409 | AC_LIBOBJ([strnlen]) | ||
| 410 | gl_PREREQ_STRNLEN | ||
| 411 | fi | ||
| 412 | gl_STRING_MODULE_INDICATOR([strnlen]) | ||
| 406 | gl_FUNC_STRTOIMAX | 413 | gl_FUNC_STRTOIMAX |
| 407 | if test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; then | 414 | if test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; then |
| 408 | AC_LIBOBJ([strtoimax]) | 415 | AC_LIBOBJ([strtoimax]) |
| @@ -1003,6 +1010,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1003 | lib/str-two-way.h | 1010 | lib/str-two-way.h |
| 1004 | lib/strftime.h | 1011 | lib/strftime.h |
| 1005 | lib/string.in.h | 1012 | lib/string.in.h |
| 1013 | lib/strnlen.c | ||
| 1006 | lib/strtoimax.c | 1014 | lib/strtoimax.c |
| 1007 | lib/strtol.c | 1015 | lib/strtol.c |
| 1008 | lib/strtoll.c | 1016 | lib/strtoll.c |
| @@ -1131,6 +1139,7 @@ AC_DEFUN([gl_FILE_LIST], [ | |||
| 1131 | m4/stdlib_h.m4 | 1139 | m4/stdlib_h.m4 |
| 1132 | m4/stpcpy.m4 | 1140 | m4/stpcpy.m4 |
| 1133 | m4/string_h.m4 | 1141 | m4/string_h.m4 |
| 1142 | m4/strnlen.m4 | ||
| 1134 | m4/strtoimax.m4 | 1143 | m4/strtoimax.m4 |
| 1135 | m4/strtoll.m4 | 1144 | m4/strtoll.m4 |
| 1136 | m4/symlink.m4 | 1145 | m4/symlink.m4 |
diff --git a/m4/strnlen.m4 b/m4/strnlen.m4 new file mode 100644 index 00000000000..c283c3ece9f --- /dev/null +++ b/m4/strnlen.m4 | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | # strnlen.m4 serial 13 | ||
| 2 | dnl Copyright (C) 2002-2003, 2005-2007, 2009-2019 Free Software Foundation, | ||
| 3 | dnl Inc. | ||
| 4 | dnl This file is free software; the Free Software Foundation | ||
| 5 | dnl gives unlimited permission to copy and/or distribute it, | ||
| 6 | dnl with or without modifications, as long as this notice is preserved. | ||
| 7 | |||
| 8 | AC_DEFUN([gl_FUNC_STRNLEN], | ||
| 9 | [ | ||
| 10 | AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) | ||
| 11 | |||
| 12 | dnl Persuade glibc <string.h> to declare strnlen(). | ||
| 13 | AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) | ||
| 14 | |||
| 15 | AC_CHECK_DECLS_ONCE([strnlen]) | ||
| 16 | if test $ac_cv_have_decl_strnlen = no; then | ||
| 17 | HAVE_DECL_STRNLEN=0 | ||
| 18 | else | ||
| 19 | m4_pushdef([AC_LIBOBJ], [:]) | ||
| 20 | dnl Note: AC_FUNC_STRNLEN does AC_LIBOBJ([strnlen]). | ||
| 21 | AC_FUNC_STRNLEN | ||
| 22 | m4_popdef([AC_LIBOBJ]) | ||
| 23 | if test $ac_cv_func_strnlen_working = no; then | ||
| 24 | REPLACE_STRNLEN=1 | ||
| 25 | fi | ||
| 26 | fi | ||
| 27 | ]) | ||
| 28 | |||
| 29 | # Prerequisites of lib/strnlen.c. | ||
| 30 | AC_DEFUN([gl_PREREQ_STRNLEN], [:]) | ||
diff --git a/src/doprnt.c b/src/doprnt.c index 5fb70634048..64bb368ee3e 100644 --- a/src/doprnt.c +++ b/src/doprnt.c | |||
| @@ -357,8 +357,8 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format, | |||
| 357 | if (fmtcpy[1] != 's') | 357 | if (fmtcpy[1] != 's') |
| 358 | minlen = atoi (&fmtcpy[1]); | 358 | minlen = atoi (&fmtcpy[1]); |
| 359 | string = va_arg (ap, char *); | 359 | string = va_arg (ap, char *); |
| 360 | tem = strlen (string); | 360 | tem = strnlen (string, STRING_BYTES_BOUND + 1); |
| 361 | if (STRING_BYTES_BOUND < tem) | 361 | if (tem == STRING_BYTES_BOUND + 1) |
| 362 | error ("String for %%s or %%S format is too long"); | 362 | error ("String for %%s or %%S format is too long"); |
| 363 | width = strwidth (string, tem); | 363 | width = strwidth (string, tem); |
| 364 | goto doit1; | 364 | goto doit1; |
diff --git a/src/emacs.c b/src/emacs.c index 1ddd10b8051..231acc0ef32 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -1520,8 +1520,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1520 | } | 1520 | } |
| 1521 | 1521 | ||
| 1522 | /* In exec'd: parse special dname into pipe and name info. */ | 1522 | /* In exec'd: parse special dname into pipe and name info. */ |
| 1523 | if (!dname_arg || !strchr (dname_arg, '\n') | 1523 | if (!dname_arg || !*dname_arg || strnlen (dname_arg, 71) == 71 |
| 1524 | || strlen (dname_arg) < 1 || strlen (dname_arg) > 70) | 1524 | || !strchr (dname_arg, '\n')) |
| 1525 | { | 1525 | { |
| 1526 | fprintf (stderr, "emacs daemon: daemon name absent or too long\n"); | 1526 | fprintf (stderr, "emacs daemon: daemon name absent or too long\n"); |
| 1527 | exit (EXIT_CANNOT_INVOKE); | 1527 | exit (EXIT_CANNOT_INVOKE); |
diff --git a/src/inotify.c b/src/inotify.c index 9a7dbb8f413..e8891aefc7a 100644 --- a/src/inotify.c +++ b/src/inotify.c | |||
| @@ -181,8 +181,7 @@ inotifyevent_to_event (Lisp_Object watch, struct inotify_event const *ev) | |||
| 181 | 181 | ||
| 182 | if (ev->len > 0) | 182 | if (ev->len > 0) |
| 183 | { | 183 | { |
| 184 | size_t const len = strlen (ev->name); | 184 | name = make_unibyte_string (ev->name, strnlen (ev->name, ev->len)); |
| 185 | name = make_unibyte_string (ev->name, min (len, ev->len)); | ||
| 186 | name = DECODE_FILE (name); | 185 | name = DECODE_FILE (name); |
| 187 | } | 186 | } |
| 188 | else | 187 | else |
diff --git a/src/json.c b/src/json.c index e2a4424463b..23234c767d8 100644 --- a/src/json.c +++ b/src/json.c | |||
| @@ -197,9 +197,7 @@ init_json (void) | |||
| 197 | static bool | 197 | static bool |
| 198 | json_has_prefix (const char *string, const char *prefix) | 198 | json_has_prefix (const char *string, const char *prefix) |
| 199 | { | 199 | { |
| 200 | size_t string_len = strlen (string); | 200 | return strncmp (string, prefix, strlen (prefix)) == 0; |
| 201 | size_t prefix_len = strlen (prefix); | ||
| 202 | return string_len >= prefix_len && memcmp (string, prefix, prefix_len) == 0; | ||
| 203 | } | 201 | } |
| 204 | 202 | ||
| 205 | /* Return whether STRING ends with SUFFIX. */ | 203 | /* Return whether STRING ends with SUFFIX. */ |
diff --git a/src/keyboard.c b/src/keyboard.c index 0d7f124f5f3..56916e0cb4e 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -7331,7 +7331,7 @@ menu_separator_name_p (const char *label) | |||
| 7331 | { | 7331 | { |
| 7332 | if (!label) | 7332 | if (!label) |
| 7333 | return 0; | 7333 | return 0; |
| 7334 | else if (strlen (label) > 3 | 7334 | else if (strnlen (label, 4) == 4 |
| 7335 | && memcmp (label, "--", 2) == 0 | 7335 | && memcmp (label, "--", 2) == 0 |
| 7336 | && label[2] != '-') | 7336 | && label[2] != '-') |
| 7337 | { | 7337 | { |
| @@ -8248,13 +8248,13 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) | |||
| 8248 | Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION); | 8248 | Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION); |
| 8249 | const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : ""; | 8249 | const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : ""; |
| 8250 | const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : ""; | 8250 | const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : ""; |
| 8251 | ptrdiff_t max_lbl = | 8251 | ptrdiff_t max_lbl_size = |
| 8252 | 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2)); | 8252 | 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2)) + 1; |
| 8253 | char *buf = xmalloc (max_lbl + 1); | 8253 | char *buf = xmalloc (max_lbl_size); |
| 8254 | Lisp_Object new_lbl; | 8254 | Lisp_Object new_lbl; |
| 8255 | ptrdiff_t caption_len = strlen (capt); | 8255 | ptrdiff_t caption_len = strnlen (capt, max_lbl_size); |
| 8256 | 8256 | ||
| 8257 | if (caption_len <= max_lbl && capt[0] != '\0') | 8257 | if (0 < caption_len && caption_len < max_lbl_size) |
| 8258 | { | 8258 | { |
| 8259 | strcpy (buf, capt); | 8259 | strcpy (buf, capt); |
| 8260 | while (caption_len > 0 && buf[caption_len - 1] == '.') | 8260 | while (caption_len > 0 && buf[caption_len - 1] == '.') |
| @@ -8263,7 +8263,8 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) | |||
| 8263 | label = capt = buf; | 8263 | label = capt = buf; |
| 8264 | } | 8264 | } |
| 8265 | 8265 | ||
| 8266 | if (strlen (label) <= max_lbl && label[0] != '\0') | 8266 | ptrdiff_t label_len = strnlen (label, max_lbl_size); |
| 8267 | if (0 < label_len && label_len < max_lbl_size) | ||
| 8267 | { | 8268 | { |
| 8268 | ptrdiff_t j; | 8269 | ptrdiff_t j; |
| 8269 | if (label != buf) | 8270 | if (label != buf) |
diff --git a/src/nsmenu.m b/src/nsmenu.m index 3fe06cda02a..817f8cff184 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m | |||
| @@ -611,7 +611,7 @@ ns_activate_menubar (struct frame *f) | |||
| 611 | const char *tpos = key; | 611 | const char *tpos = key; |
| 612 | keyEquivModMask = NSEventModifierFlagCommand; | 612 | keyEquivModMask = NSEventModifierFlagCommand; |
| 613 | 613 | ||
| 614 | if (!key || !strlen (key)) | 614 | if (!key || !*key) |
| 615 | return @""; | 615 | return @""; |
| 616 | 616 | ||
| 617 | while (*tpos == ' ' || *tpos == '(') | 617 | while (*tpos == ' ' || *tpos == '(') |
diff --git a/src/nsterm.m b/src/nsterm.m index 0ab03b46df1..8d46a49cc5e 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -9298,7 +9298,7 @@ ns_xlfd_to_fontname (const char *xlfd) | |||
| 9298 | sscanf (xlfd, "-%*[^-]-%179[^-]-", name); | 9298 | sscanf (xlfd, "-%*[^-]-%179[^-]-", name); |
| 9299 | 9299 | ||
| 9300 | /* stopgap for malformed XLFD input */ | 9300 | /* stopgap for malformed XLFD input */ |
| 9301 | if (strlen (name) == 0) | 9301 | if (!*name) |
| 9302 | strcpy (name, "Monaco"); | 9302 | strcpy (name, "Monaco"); |
| 9303 | 9303 | ||
| 9304 | /* undo hack in ns_fontname_to_xlfd, converting '$' to '-', '_' to ' ' | 9304 | /* undo hack in ns_fontname_to_xlfd, converting '$' to '-', '_' to ' ' |
diff --git a/src/process.c b/src/process.c index 6717ccb4187..15d87cf6015 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -2857,11 +2857,7 @@ set_socket_option (int s, Lisp_Object opt, Lisp_Object val) | |||
| 2857 | This should work on all systems. KFS. 2003-09-23. */ | 2857 | This should work on all systems. KFS. 2003-09-23. */ |
| 2858 | memset (devname, 0, sizeof devname); | 2858 | memset (devname, 0, sizeof devname); |
| 2859 | if (STRINGP (val)) | 2859 | if (STRINGP (val)) |
| 2860 | { | 2860 | memcpy (devname, SDATA (val), min (SBYTES (val), IFNAMSIZ)); |
| 2861 | char *arg = SSDATA (val); | ||
| 2862 | int len = min (strlen (arg), IFNAMSIZ); | ||
| 2863 | memcpy (devname, arg, len); | ||
| 2864 | } | ||
| 2865 | else if (!NILP (val)) | 2861 | else if (!NILP (val)) |
| 2866 | error ("Bad option value for %s", name); | 2862 | error ("Bad option value for %s", name); |
| 2867 | ret = setsockopt (s, sopt->optlevel, sopt->optnum, | 2863 | ret = setsockopt (s, sopt->optlevel, sopt->optnum, |
diff --git a/src/sysdep.c b/src/sysdep.c index 0910b69f8bc..b702bae5818 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -281,7 +281,7 @@ get_current_dir_name_or_unreachable (void) | |||
| 281 | pwd = get_current_dir_name (); | 281 | pwd = get_current_dir_name (); |
| 282 | if (pwd) | 282 | if (pwd) |
| 283 | { | 283 | { |
| 284 | if (strlen (pwd) < dirsize_max) | 284 | if (strnlen (pwd, dirsize_max) < dirsize_max) |
| 285 | return pwd; | 285 | return pwd; |
| 286 | free (pwd); | 286 | free (pwd); |
| 287 | errno = ERANGE; | 287 | errno = ERANGE; |
| @@ -298,7 +298,7 @@ get_current_dir_name_or_unreachable (void) | |||
| 298 | sometimes a nicer name, and using it may avoid a fatal error if a | 298 | sometimes a nicer name, and using it may avoid a fatal error if a |
| 299 | parent directory is searchable but not readable. */ | 299 | parent directory is searchable but not readable. */ |
| 300 | if (pwd | 300 | if (pwd |
| 301 | && (pwdlen = strlen (pwd)) < bufsize_max | 301 | && (pwdlen = strnlen (pwd, bufsize_max)) < bufsize_max |
| 302 | && IS_DIRECTORY_SEP (pwd[pwdlen && IS_DEVICE_SEP (pwd[1]) ? 2 : 0]) | 302 | && IS_DIRECTORY_SEP (pwd[pwdlen && IS_DEVICE_SEP (pwd[1]) ? 2 : 0]) |
| 303 | && stat (pwd, &pwdstat) == 0 | 303 | && stat (pwd, &pwdstat) == 0 |
| 304 | && stat (".", &dotstat) == 0 | 304 | && stat (".", &dotstat) == 0 |
diff --git a/src/term.c b/src/term.c index ce06e1cd4e5..8b5a710d80a 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -4400,7 +4400,7 @@ vfatal (const char *str, va_list ap) | |||
| 4400 | { | 4400 | { |
| 4401 | fprintf (stderr, "emacs: "); | 4401 | fprintf (stderr, "emacs: "); |
| 4402 | vfprintf (stderr, str, ap); | 4402 | vfprintf (stderr, str, ap); |
| 4403 | if (!(strlen (str) > 0 && str[strlen (str) - 1] == '\n')) | 4403 | if (! (str[0] && str[strlen (str) - 1] == '\n')) |
| 4404 | fprintf (stderr, "\n"); | 4404 | fprintf (stderr, "\n"); |
| 4405 | exit (1); | 4405 | exit (1); |
| 4406 | } | 4406 | } |
diff --git a/src/xdisp.c b/src/xdisp.c index 25e8932945e..9f63ef4b180 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -24341,9 +24341,7 @@ store_mode_line_string (const char *string, Lisp_Object lisp_string, | |||
| 24341 | 24341 | ||
| 24342 | if (string != NULL) | 24342 | if (string != NULL) |
| 24343 | { | 24343 | { |
| 24344 | len = strlen (string); | 24344 | len = strnlen (string, precision <= 0 ? SIZE_MAX : precision); |
| 24345 | if (precision > 0 && len > precision) | ||
| 24346 | len = precision; | ||
| 24347 | lisp_string = make_string (string, len); | 24345 | lisp_string = make_string (string, len); |
| 24348 | if (NILP (props)) | 24346 | if (NILP (props)) |
| 24349 | props = mode_line_string_face_prop; | 24347 | props = mode_line_string_face_prop; |