From: Paul Eggert Date: Tue, 25 Jun 2019 21:53:39 +0000 (-0700) Subject: Avoid some strlen work, primarily via strnlen X-Git-Tag: emacs-27.0.90~2222 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=d7c6836288c91bb639956cb8c748dd6597c55cd4;p=emacs.git 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. --- 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=' manywarnings memmem-simple memrchr minmax mkostemp mktime nstrftime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat regex sig2str socklen stat-time std-gnu11 stdalign stddef stdio - stpcpy strtoimax symlink sys_stat sys_time + stpcpy strnlen strtoimax symlink sys_stat sys_time tempname time time_r time_rz timegm timer-time timespec-add timespec-sub update-copyright unlocked-io utimens 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) } *cp = '\0'; - if (strlen (lp) > 0) + if (*lp) { lang = get_language_from_interpreter (lp); if (lang != NULL && lang->function != NULL) @@ -2012,7 +2012,7 @@ pfnote (char *name, bool is_func, char *linestart, int linelen, int lno, np->left = np->right = NULL; if (CTAGS && !cxref_style) { - if (strlen (linestart) < 50) + if (strnlen (linestart, 50) < 50) np->regex = concat (linestart, "$", ""); else np->regex = savenstr (linestart, 50); @@ -5883,20 +5883,15 @@ HTML_labels (FILE *inf) * Original code by Sunichirou Sugou (1989) * Rewritten by Anders Lindgren (1996) */ -static size_t prolog_pr (char *, char *); +static ptrdiff_t prolog_pr (char *, char *, ptrdiff_t); static void prolog_skip_comment (linebuffer *, FILE *); static size_t prolog_atom (char *, size_t); static void Prolog_functions (FILE *inf) { - char *cp, *last; - size_t len; - size_t allocated; - - allocated = 0; - len = 0; - last = NULL; + char *cp, *last = NULL; + ptrdiff_t lastlen = 0, allocated = 0; LOOP_ON_INPUT_LINES (inf, lb, cp) { @@ -5906,17 +5901,22 @@ Prolog_functions (FILE *inf) continue; else if (cp[0] == '/' && cp[1] == '*') /* comment. */ prolog_skip_comment (&lb, inf); - else if ((len = prolog_pr (cp, last)) > 0) + else { - /* Predicate or rule. Store the function name so that we - only generate a tag for the first clause. */ - if (last == NULL) - last = xnew (len + 1, char); - else if (len + 1 > allocated) - xrnew (last, len + 1, char); - allocated = len + 1; - memcpy (last, cp, len); - last[len] = '\0'; + ptrdiff_t len = prolog_pr (cp, last, lastlen); + if (0 < len) + { + /* Store the predicate name to avoid generating duplicate + tags later. */ + if (allocated <= len) + { + xrnew (last, len + 1, char); + allocated = len + 1; + } + memcpy (last, cp, len); + last[len] = '\0'; + lastlen = len; + } } } free (last); @@ -5949,33 +5949,25 @@ prolog_skip_comment (linebuffer *plb, FILE *inf) * Return the size of the name of the predicate or rule, or 0 if no * header was found. */ -static size_t -prolog_pr (char *s, char *last) - - /* Name of last clause. */ +static ptrdiff_t +prolog_pr (char *s, char *last, ptrdiff_t lastlen) { - size_t pos; - size_t len; - - pos = prolog_atom (s, 0); - if (! pos) + ptrdiff_t len = prolog_atom (s, 0); + if (len == 0) return 0; + ptrdiff_t pos = skip_spaces (s + len) - s; - len = pos; - pos = skip_spaces (s + pos) - s; - + /* Save only the first clause. */ if ((s[pos] == '.' || (s[pos] == '(' && (pos += 1)) || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2))) - && (last == NULL /* save only the first clause */ - || len != strlen (last) - || !strneq (s, last, len))) - { - make_tag (s, len, true, s, pos, lineno, linecharno); - return len; - } - else - return 0; + && ! (lastlen == len && memcmp (s, last, len) == 0)) + { + make_tag (s, len, true, s, pos, lineno, linecharno); + return len; + } + + return 0; } /* @@ -6043,21 +6035,15 @@ prolog_atom (char *s, size_t pos) * Assumes that Erlang functions start at column 0. * Original code by Anders Lindgren (1996) */ -static int erlang_func (char *, char *, int *); +static int erlang_func (char *, char *, ptrdiff_t, ptrdiff_t *); static void erlang_attribute (char *); static int erlang_atom (char *); static void Erlang_functions (FILE *inf) { - char *cp, *last; - int len; - int allocated; - int name_offset = 0; - - allocated = 0; - len = 0; - last = NULL; + char *cp, *last = NULL; + ptrdiff_t lastlen = 0, allocated = 0; LOOP_ON_INPUT_LINES (inf, lb, cp) { @@ -6078,19 +6064,23 @@ Erlang_functions (FILE *inf) last = NULL; } } - else if ((len = erlang_func (cp, last, &name_offset)) > 0) + else { - /* - * Function. Store the function name so that we only - * generates a tag for the first clause. - */ - if (last == NULL) - last = xnew (len + 1, char); - else if (len + 1 > allocated) - xrnew (last, len + 1, char); - allocated = len + 1; - memcpy (last, cp + name_offset, len); - last[len] = '\0'; + ptrdiff_t name_offset; + ptrdiff_t len = erlang_func (cp, last, lastlen, &name_offset); + if (0 < len) + { + /* Store the function name to avoid generating duplicate + tags later. */ + if (allocated <= len) + { + xrnew (last, len + 1, char); + allocated = len + 1; + } + memcpy (last, cp + name_offset, len); + last[len] = '\0'; + lastlen = len; + } } } free (last); @@ -6108,40 +6098,27 @@ Erlang_functions (FILE *inf) * was found. */ static int -erlang_func (char *s, char *last, int *name_offset) - - /* Name of last clause. */ +erlang_func (char *s, char *last, ptrdiff_t lastlen, ptrdiff_t *name_offset) { - int pos; - int len; char *name = s; - - pos = erlang_atom (s); - if (pos < 1) + ptrdiff_t len = erlang_atom (s); + if (len == 0) return 0; - - len = pos; - pos = skip_spaces (s + pos) - s; + ptrdiff_t pos = skip_spaces (s + len) - s; /* If the name is quoted, the quotes are not part of the name. */ - if (len > 2 && name[0] == '\'' && name[len - 1] == '\'') - { - *name_offset = 1; - name++; - len -= 2; - } - else - *name_offset = 0; + bool quoted = 2 < len && name[0] == '\'' && name[len - 1] == '\''; + name += quoted; + len -= 2 * quoted; /* Save only the first clause. */ if (s[pos++] == '(' - && (last == NULL - || len != (int)strlen (last) - || !strneq (name, last, len))) - { - make_tag (name, len, true, s, pos, lineno, linecharno); - return len; - } + && ! (lastlen == len && memcmp (name, last, len) == 0)) + { + make_tag (s, len, true, s, pos, lineno, linecharno); + *name_offset = quoted; + return len; + } return 0; } @@ -6363,7 +6340,7 @@ add_regex (char *regexp_pattern, language *lang) single_line = false; /* dot does not match newline */ - if (strlen (regexp_pattern) < 3) + if (strnlen (regexp_pattern, 3) < 3) { error ("null regexp"); 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) /* * I really shouldn't use the pop_error variable like this, but.... */ - if (strlen (username) > ERROR_MAX - 6) + if (strnlen (username, ERROR_MAX - 6 + 1) == ERROR_MAX - 6 + 1) { pop_close (server); strcpy (pop_error, @@ -299,7 +299,7 @@ pop_open (char *host, char *username, char *password, int flags) return (0); } - if (strlen (password) > ERROR_MAX - 6) + if (strnlen (password, ERROR_MAX - 6 + 1) == ERROR_MAX - 6 + 1) { pop_close (server); 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) if (! user) lose_syserr ("Couldn't determine user id"); data = argv[optind + 2]; - if (strlen (data) > MAX_DATA_LEN) + if (strnlen (data, MAX_DATA_LEN + 1) == MAX_DATA_LEN + 1) data[MAX_DATA_LEN] = '\0'; nl = strchr (data, '\n'); 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 @@ # stddef \ # stdio \ # stpcpy \ +# strnlen \ # strtoimax \ # symlink \ # sys_stat \ @@ -1075,7 +1076,6 @@ gl_GNULIB_ENABLED_getdtablesize = @gl_GNULIB_ENABLED_getdtablesize@ gl_GNULIB_ENABLED_getgroups = @gl_GNULIB_ENABLED_getgroups@ gl_GNULIB_ENABLED_malloca = @gl_GNULIB_ENABLED_malloca@ gl_GNULIB_ENABLED_open = @gl_GNULIB_ENABLED_open@ -gl_GNULIB_ENABLED_pathmax = @gl_GNULIB_ENABLED_pathmax@ gl_GNULIB_ENABLED_strtoll = @gl_GNULIB_ENABLED_strtoll@ gl_LIBOBJS = @gl_LIBOBJS@ gl_LTLIBOBJS = @gl_LTLIBOBJS@ @@ -1110,7 +1110,6 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -2811,6 +2810,17 @@ EXTRA_DIST += string.in.h endif ## end gnulib module string +## begin gnulib module strnlen +ifeq (,$(OMIT_GNULIB_MODULE_strnlen)) + + +EXTRA_DIST += strnlen.c + +EXTRA_libgnu_a_SOURCES += strnlen.c + +endif +## end gnulib module strnlen + ## begin gnulib module strtoimax ifeq (,$(OMIT_GNULIB_MODULE_strtoimax)) 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 @@ +/* Find the length of STRING, but scan at most MAXLEN characters. + Copyright (C) 2005-2007, 2009-2019 Free Software Foundation, Inc. + Written by Simon Josefsson. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . */ + +#include + +#include + +/* Find the length of STRING, but scan at most MAXLEN characters. + If no '\0' terminator is found in that many characters, return MAXLEN. */ + +size_t +strnlen (const char *string, size_t maxlen) +{ + const char *end = memchr (string, '\0', maxlen); + return end ? (size_t) (end - string) : maxlen; +} 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) { int separator_p = 0; - if (strlen (label) >= 3 - && memcmp (label, "--:", 3) == 0) + if (strncmp (label, "--:", 3) == 0) { static struct separator_table { @@ -1276,7 +1275,7 @@ lw_separator_p (const char *label, enum menu_separator *type, int motif_p) break; } } - else if (strlen (label) > 3 + else if (strnlen (label, 4) == 4 && memcmp (label, "--", 2) == 0 && label[2] != '-') { 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], # Code from module stdlib: # Code from module stpcpy: # Code from module string: + # Code from module strnlen: # Code from module strtoimax: # Code from module strtoll: # Code from module symlink: @@ -403,6 +404,12 @@ AC_DEFUN([gl_INIT], fi gl_STRING_MODULE_INDICATOR([stpcpy]) gl_HEADER_STRING_H + gl_FUNC_STRNLEN + if test $HAVE_DECL_STRNLEN = 0 || test $REPLACE_STRNLEN = 1; then + AC_LIBOBJ([strnlen]) + gl_PREREQ_STRNLEN + fi + gl_STRING_MODULE_INDICATOR([strnlen]) gl_FUNC_STRTOIMAX if test $HAVE_DECL_STRTOIMAX = 0 || test $REPLACE_STRTOIMAX = 1; then AC_LIBOBJ([strtoimax]) @@ -1003,6 +1010,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/str-two-way.h lib/strftime.h lib/string.in.h + lib/strnlen.c lib/strtoimax.c lib/strtol.c lib/strtoll.c @@ -1131,6 +1139,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/stdlib_h.m4 m4/stpcpy.m4 m4/string_h.m4 + m4/strnlen.m4 m4/strtoimax.m4 m4/strtoll.m4 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 @@ +# strnlen.m4 serial 13 +dnl Copyright (C) 2002-2003, 2005-2007, 2009-2019 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_STRNLEN], +[ + AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS]) + + dnl Persuade glibc to declare strnlen(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([strnlen]) + if test $ac_cv_have_decl_strnlen = no; then + HAVE_DECL_STRNLEN=0 + else + m4_pushdef([AC_LIBOBJ], [:]) + dnl Note: AC_FUNC_STRNLEN does AC_LIBOBJ([strnlen]). + AC_FUNC_STRNLEN + m4_popdef([AC_LIBOBJ]) + if test $ac_cv_func_strnlen_working = no; then + REPLACE_STRNLEN=1 + fi + fi +]) + +# Prerequisites of lib/strnlen.c. +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, if (fmtcpy[1] != 's') minlen = atoi (&fmtcpy[1]); string = va_arg (ap, char *); - tem = strlen (string); - if (STRING_BYTES_BOUND < tem) + tem = strnlen (string, STRING_BYTES_BOUND + 1); + if (tem == STRING_BYTES_BOUND + 1) error ("String for %%s or %%S format is too long"); width = strwidth (string, tem); 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 } /* In exec'd: parse special dname into pipe and name info. */ - if (!dname_arg || !strchr (dname_arg, '\n') - || strlen (dname_arg) < 1 || strlen (dname_arg) > 70) + if (!dname_arg || !*dname_arg || strnlen (dname_arg, 71) == 71 + || !strchr (dname_arg, '\n')) { fprintf (stderr, "emacs daemon: daemon name absent or too long\n"); 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) if (ev->len > 0) { - size_t const len = strlen (ev->name); - name = make_unibyte_string (ev->name, min (len, ev->len)); + name = make_unibyte_string (ev->name, strnlen (ev->name, ev->len)); name = DECODE_FILE (name); } 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) static bool json_has_prefix (const char *string, const char *prefix) { - size_t string_len = strlen (string); - size_t prefix_len = strlen (prefix); - return string_len >= prefix_len && memcmp (string, prefix, prefix_len) == 0; + return strncmp (string, prefix, strlen (prefix)) == 0; } /* 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) { if (!label) return 0; - else if (strlen (label) > 3 + else if (strnlen (label, 4) == 4 && memcmp (label, "--", 2) == 0 && label[2] != '-') { @@ -8248,13 +8248,13 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION); const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : ""; const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : ""; - ptrdiff_t max_lbl = - 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2)); - char *buf = xmalloc (max_lbl + 1); + ptrdiff_t max_lbl_size = + 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2)) + 1; + char *buf = xmalloc (max_lbl_size); Lisp_Object new_lbl; - ptrdiff_t caption_len = strlen (capt); + ptrdiff_t caption_len = strnlen (capt, max_lbl_size); - if (caption_len <= max_lbl && capt[0] != '\0') + if (0 < caption_len && caption_len < max_lbl_size) { strcpy (buf, capt); while (caption_len > 0 && buf[caption_len - 1] == '.') @@ -8263,7 +8263,8 @@ parse_tool_bar_item (Lisp_Object key, Lisp_Object item) label = capt = buf; } - if (strlen (label) <= max_lbl && label[0] != '\0') + ptrdiff_t label_len = strnlen (label, max_lbl_size); + if (0 < label_len && label_len < max_lbl_size) { ptrdiff_t j; 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) const char *tpos = key; keyEquivModMask = NSEventModifierFlagCommand; - if (!key || !strlen (key)) + if (!key || !*key) return @""; 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) sscanf (xlfd, "-%*[^-]-%179[^-]-", name); /* stopgap for malformed XLFD input */ - if (strlen (name) == 0) + if (!*name) strcpy (name, "Monaco"); /* 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) This should work on all systems. KFS. 2003-09-23. */ memset (devname, 0, sizeof devname); if (STRINGP (val)) - { - char *arg = SSDATA (val); - int len = min (strlen (arg), IFNAMSIZ); - memcpy (devname, arg, len); - } + memcpy (devname, SDATA (val), min (SBYTES (val), IFNAMSIZ)); else if (!NILP (val)) error ("Bad option value for %s", name); 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) pwd = get_current_dir_name (); if (pwd) { - if (strlen (pwd) < dirsize_max) + if (strnlen (pwd, dirsize_max) < dirsize_max) return pwd; free (pwd); errno = ERANGE; @@ -298,7 +298,7 @@ get_current_dir_name_or_unreachable (void) sometimes a nicer name, and using it may avoid a fatal error if a parent directory is searchable but not readable. */ if (pwd - && (pwdlen = strlen (pwd)) < bufsize_max + && (pwdlen = strnlen (pwd, bufsize_max)) < bufsize_max && IS_DIRECTORY_SEP (pwd[pwdlen && IS_DEVICE_SEP (pwd[1]) ? 2 : 0]) && stat (pwd, &pwdstat) == 0 && 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) { fprintf (stderr, "emacs: "); vfprintf (stderr, str, ap); - if (!(strlen (str) > 0 && str[strlen (str) - 1] == '\n')) + if (! (str[0] && str[strlen (str) - 1] == '\n')) fprintf (stderr, "\n"); exit (1); } 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, if (string != NULL) { - len = strlen (string); - if (precision > 0 && len > precision) - len = precision; + len = strnlen (string, precision <= 0 ? SIZE_MAX : precision); lisp_string = make_string (string, len); if (NILP (props)) props = mode_line_string_face_prop;