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>
This commit is contained in:
committed by
Christian Brabandt
parent
8311e7d6b4
commit
fff0132399
57
src/misc1.c
57
src/misc1.c
@ -1401,16 +1401,16 @@ expand_env_save_opt(char_u *src, int one)
|
||||
* 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 @@ expand_env_esc(
|
||||
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 @@ expand_env_esc(
|
||||
*/
|
||||
{
|
||||
char_u test[MAXPATHL], paths[MAXPATHL];
|
||||
size_t testlen;
|
||||
char_u *path, *next_path, *ptr;
|
||||
stat_T st;
|
||||
|
||||
@ -1588,14 +1590,20 @@ expand_env_esc(
|
||||
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 @@ expand_env_esc(
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ expand_env_esc(
|
||||
|
||||
}
|
||||
*dst = NUL;
|
||||
|
||||
return (size_t)(dst - dst_start);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user