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:
John Marriott
2025-06-18 18:15:31 +02:00
committed by Christian Brabandt
parent 8311e7d6b4
commit fff0132399
8 changed files with 55 additions and 40 deletions

View File

@ -5351,14 +5351,13 @@ vim_tempname(
long nr; long nr;
long off; long off;
# endif # endif
size_t itmplen;
// Expand $TMP, leave room for "/v1100000/999999999". // Expand $TMP, leave room for "/v1100000/999999999".
// Skip the directory check if the expansion fails. // Skip the directory check if the expansion fails.
expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 20); itmplen = expand_env((char_u *)tempdirs[i], itmp, TEMPNAMELEN - 20);
if (itmp[0] != '$' && mch_isdir(itmp)) if (itmp[0] != '$' && mch_isdir(itmp))
{ {
size_t itmplen = STRLEN(itmp);
// directory exists // directory exists
if (!after_pathsep(itmp, itmp + itmplen)) if (!after_pathsep(itmp, itmp + itmplen))
{ {

View File

@ -1820,11 +1820,10 @@ find_file_in_path_option(
// copy file name into NameBuff, expanding environment variables // copy file name into NameBuff, expanding environment variables
save_char = ptr[len]; save_char = ptr[len];
ptr[len] = NUL; ptr[len] = NUL;
expand_env_esc(ptr, NameBuff, MAXPATHL, FALSE, TRUE, NULL); file_to_findlen = expand_env_esc(ptr, NameBuff, MAXPATHL, FALSE, TRUE, NULL);
ptr[len] = save_char; ptr[len] = save_char;
vim_free(*file_to_find); vim_free(*file_to_find);
file_to_findlen = STRLEN(NameBuff);
*file_to_find = vim_strnsave(NameBuff, file_to_findlen); *file_to_find = vim_strnsave(NameBuff, file_to_findlen);
if (*file_to_find == NULL) // out of memory if (*file_to_find == NULL) // out of memory
{ {

View File

@ -548,8 +548,7 @@ cs_add_common(
if ((fname = alloc(MAXPATHL + 1)) == NULL) if ((fname = alloc(MAXPATHL + 1)) == NULL)
goto add_err; goto add_err;
expand_env((char_u *)arg1, (char_u *)fname, MAXPATHL); len = expand_env((char_u *)arg1, (char_u *)fname, MAXPATHL);
len = STRLEN(fname);
fbuf = (char_u *)fname; fbuf = (char_u *)fname;
(void)modify_fname((char_u *)":p", FALSE, &usedlen, (void)modify_fname((char_u *)":p", FALSE, &usedlen,
(char_u **)&fname, &fbuf, &len); (char_u **)&fname, &fbuf, &len);
@ -829,6 +828,7 @@ cs_create_connection(int i)
int cmdlen; int cmdlen;
int len; int len;
char *prog, *cmd, *ppath = NULL; char *prog, *cmd, *ppath = NULL;
size_t proglen;
#ifdef MSWIN #ifdef MSWIN
int fd; int fd;
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa;
@ -916,10 +916,10 @@ err_closing:
goto err_closing; goto err_closing;
#endif #endif
} }
expand_env(p_csprg, (char_u *)prog, MAXPATHL); proglen = expand_env(p_csprg, (char_u *)prog, MAXPATHL);
// alloc space to hold the cscope command // alloc space to hold the cscope command
cmdlen = (int)(strlen(prog) + strlen(csinfo[i].fname) + 32); cmdlen = (int)(proglen + strlen(csinfo[i].fname) + 32);
if (csinfo[i].ppath) if (csinfo[i].ppath)
{ {
// expand the prepend path for env var's // expand the prepend path for env var's
@ -933,9 +933,7 @@ err_closing:
goto err_closing; goto err_closing;
#endif #endif
} }
expand_env((char_u *)csinfo[i].ppath, (char_u *)ppath, MAXPATHL); cmdlen += (int)expand_env((char_u *)csinfo[i].ppath, (char_u *)ppath, MAXPATHL);
cmdlen += (int)strlen(ppath);
} }
if (csinfo[i].flags) if (csinfo[i].flags)

View File

@ -540,10 +540,9 @@ fname2fnum(xfmark_T *fm)
#endif #endif
)) ))
{ {
int len; size_t len;
expand_env((char_u *)"~/", NameBuff, MAXPATHL); len = expand_env((char_u *)"~/", NameBuff, MAXPATHL);
len = (int)STRLEN(NameBuff);
vim_strncpy(NameBuff + len, fm->fname + 2, MAXPATHL - len - 1); vim_strncpy(NameBuff + len, fm->fname + 2, MAXPATHL - len - 1);
} }
else else

View File

@ -1401,16 +1401,16 @@ expand_env_save_opt(char_u *src, int one)
* Skips over "\ ", "\~" and "\$" (not for Win32 though). * Skips over "\ ", "\~" and "\$" (not for Win32 though).
* If anything fails no expansion is done and dst equals src. * If anything fails no expansion is done and dst equals src.
*/ */
void size_t
expand_env( expand_env(
char_u *src, // input string e.g. "$HOME/vim.hlp" char_u *src, // input string e.g. "$HOME/vim.hlp"
char_u *dst, // where to put the result char_u *dst, // where to put the result
int dstlen) // maximum length of 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( expand_env_esc(
char_u *srcp, // input string e.g. "$HOME/vim.hlp" char_u *srcp, // input string e.g. "$HOME/vim.hlp"
char_u *dst, // where to put the result 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 mustfree; // var was allocated, need to free it later
int at_start = TRUE; // at start of a name int at_start = TRUE; // at start of a name
int startstr_len = 0; int startstr_len = 0;
char_u *dst_start = dst;
if (startstr != NULL) if (startstr != NULL)
startstr_len = (int)STRLEN(startstr); startstr_len = (int)STRLEN(startstr);
@ -1577,6 +1578,7 @@ expand_env_esc(
*/ */
{ {
char_u test[MAXPATHL], paths[MAXPATHL]; char_u test[MAXPATHL], paths[MAXPATHL];
size_t testlen;
char_u *path, *next_path, *ptr; char_u *path, *next_path, *ptr;
stat_T st; stat_T st;
@ -1588,14 +1590,20 @@ expand_env_esc(
next_path++); next_path++);
if (*next_path) if (*next_path)
*next_path++ = NUL; *next_path++ = NUL;
STRCPY(test, path); testlen = vim_snprintf_safelen(
STRCAT(test, "/"); (char *)test,
STRCAT(test, dst + 1); sizeof(test),
"%s/%s",
path,
dst + 1);
if (mch_stat(test, &st) == 0) if (mch_stat(test, &st) == 0)
{ {
var = alloc(STRLEN(test) + 1); var = alloc(testlen + 1);
if (var != NULL)
{
STRCPY(var, test); STRCPY(var, test);
mustfree = TRUE; mustfree = TRUE;
}
break; break;
} }
} }
@ -1641,12 +1649,14 @@ expand_env_esc(
} }
} }
if (var != NULL && *var != NUL if (var != NULL && *var != NUL)
&& (STRLEN(var) + STRLEN(tail) + 1 < (unsigned)dstlen)) {
c = (int)STRLEN(var);
if (c + STRLEN(tail) + 1 < (unsigned)dstlen)
{ {
STRCPY(dst, var); STRCPY(dst, var);
dstlen -= (int)STRLEN(var); dstlen -= c;
c = (int)STRLEN(var);
// if var[] ends in a path separator and tail[] starts // if var[] ends in a path separator and tail[] starts
// with it, skip a character // with it, skip a character
if (after_pathsep(dst, dst + c) if (after_pathsep(dst, dst + c)
@ -1659,6 +1669,7 @@ expand_env_esc(
src = tail; src = tail;
copy_char = FALSE; copy_char = FALSE;
} }
}
if (mustfree) if (mustfree)
vim_free(var); vim_free(var);
} }
@ -1692,6 +1703,8 @@ expand_env_esc(
} }
*dst = NUL; *dst = NUL;
return (size_t)(dst - dst_start);
} }
/* /*

View File

@ -29,8 +29,8 @@ void free_users(void);
void init_vimdir(void); void init_vimdir(void);
char_u *expand_env_save(char_u *src); char_u *expand_env_save(char_u *src);
char_u *expand_env_save_opt(char_u *src, int one); char_u *expand_env_save_opt(char_u *src, int one);
void expand_env(char_u *src, char_u *dst, int dstlen); size_t expand_env(char_u *src, char_u *dst, int dstlen);
void expand_env_esc(char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr); size_t expand_env_esc(char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr);
char_u *vim_getenv(char_u *name, int *mustfree); char_u *vim_getenv(char_u *name, int *mustfree);
void vim_unsetenv(char_u *var); void vim_unsetenv(char_u *var);
void vim_unsetenv_ext(char_u *var); void vim_unsetenv_ext(char_u *var);

View File

@ -709,6 +709,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1467,
/**/ /**/
1466, 1466,
/**/ /**/

View File

@ -99,6 +99,8 @@ viminfo_filename(char_u *file)
{ {
if (file == NULL || *file == NUL) if (file == NULL || *file == NUL)
{ {
size_t len;
if (*p_viminfofile != NUL) if (*p_viminfofile != NUL)
file = p_viminfofile; file = p_viminfofile;
else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL) else if ((file = find_viminfo_parameter('n')) == NULL || *file == NUL)
@ -127,9 +129,12 @@ viminfo_filename(char_u *file)
#endif #endif
file = (char_u *)VIMINFO_FILE; file = (char_u *)VIMINFO_FILE;
} }
expand_env(file, NameBuff, MAXPATHL); len = expand_env(file, NameBuff, MAXPATHL);
file = NameBuff; file = NameBuff;
return vim_strnsave(file, len);
} }
return vim_strsave(file); return vim_strsave(file);
} }