patch 9.1.1467: too many strlen() calls
Problem: too many strlen() calls
Solution: Change expand_env() to return string length
(John Marriott)
This commit does the following changes:
- In expand_env_esc():
- return the length of the returned dst string.
- refactor to remove some calls to STRLEN() and STRCAT()
- add check for out-of-memory condition.
- Change call sites in various source files to use the return value
closes: #17561
Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/misc1.c b/src/misc1.c
index 142a616..4571ff2 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -1401,16 +1401,16 @@
* Skips over "\ ", "\~" and "\$" (not for Win32 though).
* If anything fails no expansion is done and dst equals src.
*/
- void
+ size_t
expand_env(
char_u *src, // input string e.g. "$HOME/vim.hlp"
char_u *dst, // where to put the result
int dstlen) // maximum length of the result
{
- expand_env_esc(src, dst, dstlen, FALSE, FALSE, NULL);
+ return expand_env_esc(src, dst, dstlen, FALSE, FALSE, NULL);
}
- void
+ size_t
expand_env_esc(
char_u *srcp, // input string e.g. "$HOME/vim.hlp"
char_u *dst, // where to put the result
@@ -1427,6 +1427,7 @@
int mustfree; // var was allocated, need to free it later
int at_start = TRUE; // at start of a name
int startstr_len = 0;
+ char_u *dst_start = dst;
if (startstr != NULL)
startstr_len = (int)STRLEN(startstr);
@@ -1577,6 +1578,7 @@
*/
{
char_u test[MAXPATHL], paths[MAXPATHL];
+ size_t testlen;
char_u *path, *next_path, *ptr;
stat_T st;
@@ -1588,14 +1590,20 @@
next_path++);
if (*next_path)
*next_path++ = NUL;
- STRCPY(test, path);
- STRCAT(test, "/");
- STRCAT(test, dst + 1);
+ testlen = vim_snprintf_safelen(
+ (char *)test,
+ sizeof(test),
+ "%s/%s",
+ path,
+ dst + 1);
if (mch_stat(test, &st) == 0)
{
- var = alloc(STRLEN(test) + 1);
- STRCPY(var, test);
- mustfree = TRUE;
+ var = alloc(testlen + 1);
+ if (var != NULL)
+ {
+ STRCPY(var, test);
+ mustfree = TRUE;
+ }
break;
}
}
@@ -1641,23 +1649,26 @@
}
}
- if (var != NULL && *var != NUL
- && (STRLEN(var) + STRLEN(tail) + 1 < (unsigned)dstlen))
+ if (var != NULL && *var != NUL)
{
- STRCPY(dst, var);
- dstlen -= (int)STRLEN(var);
c = (int)STRLEN(var);
- // if var[] ends in a path separator and tail[] starts
- // with it, skip a character
- if (after_pathsep(dst, dst + c)
+
+ if (c + STRLEN(tail) + 1 < (unsigned)dstlen)
+ {
+ STRCPY(dst, var);
+ dstlen -= c;
+ // if var[] ends in a path separator and tail[] starts
+ // with it, skip a character
+ if (after_pathsep(dst, dst + c)
#if defined(BACKSLASH_IN_FILENAME) || defined(AMIGA)
- && dst[c - 1] != ':'
+ && dst[c - 1] != ':'
#endif
- && vim_ispathsep(*tail))
- ++tail;
- dst += c;
- src = tail;
- copy_char = FALSE;
+ && vim_ispathsep(*tail))
+ ++tail;
+ dst += c;
+ src = tail;
+ copy_char = FALSE;
+ }
}
if (mustfree)
vim_free(var);
@@ -1692,6 +1703,8 @@
}
*dst = NUL;
+
+ return (size_t)(dst - dst_start);
}
/*