0
0
mirror of https://github.com/vim/vim.git synced 2025-08-26 20:03:41 -04:00

patch 9.1.1050: too many strlen() calls in os_unix.c

Problem:  too many strlen() calls in os_unix.c
Solution: refactor os_unix.c and remove calls to strlen()
          (John Marriott)

closes: #16496

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-01-23 20:05:29 +01:00 committed by Christian Brabandt
parent f400a0cc41
commit efc41a5958
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
2 changed files with 120 additions and 77 deletions

View File

@ -1835,11 +1835,13 @@ may_restore_clipboard(void)
void
ex_xrestore(exarg_T *eap)
{
if (eap->arg != NULL && STRLEN(eap->arg) > 0)
size_t arglen;
if (eap->arg != NULL && (arglen = STRLEN(eap->arg)) > 0)
{
if (xterm_display_allocated)
vim_free(xterm_display);
xterm_display = (char *)vim_strsave(eap->arg);
xterm_display = (char *)vim_strnsave(eap->arg, arglen);
xterm_display_allocated = TRUE;
}
smsg(_("restoring display %s"), xterm_display == NULL
@ -2625,7 +2627,7 @@ strerror(int err)
if (err > 0 && err < sys_nerr)
return (sys_errlist[err]);
sprintf(er, "Error %d", err);
snprintf(er, sizeof(er), "Error %d", err);
return er;
}
#endif
@ -2662,7 +2664,7 @@ mch_FullName(
int len,
int force) // also expand when already absolute path
{
int l;
int buflen = 0;
#ifdef HAVE_FCHDIR
int fd = -1;
static int dont_fchdir = FALSE; // TRUE when fchdir() doesn't work
@ -2778,6 +2780,8 @@ mch_FullName(
}
if (p != NULL)
{
int l;
#ifdef HAVE_FCHDIR
if (fd >= 0)
{
@ -2800,23 +2804,29 @@ mch_FullName(
close(fd);
#endif
l = STRLEN(buf);
if (l >= len - 1)
buflen = (int)STRLEN(buf);
if (buflen >= len - 1)
retval = FAIL; // no space for trailing "/"
#ifndef VMS
else if (l > 0 && buf[l - 1] != '/' && *fname != NUL
else if (buflen > 0 && buf[buflen - 1] != PATHSEP && *fname != NUL
&& STRCMP(fname, ".") != 0)
STRCAT(buf, "/");
{
STRCPY(buf + buflen, PATHSEPSTR);
buflen += STRLEN_LITERAL(PATHSEPSTR);
}
#endif
}
if (buflen == 0)
buflen = (int)STRLEN(buf);
// Catch file names which are too long.
if (retval == FAIL || (int)(STRLEN(buf) + STRLEN(fname)) >= len)
if (retval == FAIL || (int)(buflen + STRLEN(fname)) >= len)
return FAIL;
// Do not append ".", "/dir/." is equal to "/dir".
if (STRCMP(fname, ".") != 0)
STRCAT(buf, fname);
STRCPY(buf + buflen, fname);
return OK;
}
@ -2850,6 +2860,7 @@ fname_case(
{
struct stat st;
char_u *slash, *tail;
size_t taillen;
DIR *dirp;
struct dirent *dp;
@ -2874,12 +2885,13 @@ fname_case(
if (dirp == NULL)
return;
taillen = STRLEN(tail);
while ((dp = readdir(dirp)) != NULL)
{
// Only accept names that differ in case and are the same byte
// length. TODO: accept different length name.
if (STRICMP(tail, dp->d_name) == 0
&& STRLEN(tail) == STRLEN(dp->d_name))
&& taillen == STRLEN(dp->d_name))
{
char_u newname[MAXPATHL + 1];
struct stat st2;
@ -3054,8 +3066,7 @@ mch_copy_sec(char_u *from_file, char_u *to_file)
if (size <= 0)
return;
for (index = 0 ; index < (int)(sizeof(smack_copied_attributes)
/ sizeof(smack_copied_attributes)[0]) ; index++)
for (index = 0 ; index < (int)ARRAY_LENGTH(smack_copied_attributes); index++)
{
// get the name of the attribute to copy
name = smack_copied_attributes[index];
@ -3220,12 +3231,19 @@ mch_get_acl(char_u *fname UNUSED)
vim_acl_solaris_T *aclent;
aclent = malloc(sizeof(vim_acl_solaris_T));
if (aclent == NULL)
return NULL;
if ((aclent->acl_cnt = acl((char *)fname, GETACLCNT, 0, NULL)) < 0)
{
free(aclent);
return NULL;
}
aclent->acl_entry = malloc(aclent->acl_cnt * sizeof(aclent_t));
if (aclent->acl_entry == NULL)
{
free(aclent);
return NULL;
}
if (acl((char *)fname, GETACL, aclent->acl_cnt, aclent->acl_entry) < 0)
{
free(aclent->acl_entry);
@ -3240,13 +3258,15 @@ mch_get_acl(char_u *fname UNUSED)
aclsize = sizeof(struct acl);
aclent = malloc(aclsize);
if (aclent == NULL)
return NULL;
if (statacl((char *)fname, STX_NORMAL, aclent, aclsize) < 0)
{
if (errno == ENOSPC)
{
aclsize = aclent->acl_len;
aclent = realloc(aclent, aclsize);
if (statacl((char *)fname, STX_NORMAL, aclent, aclsize) < 0)
if (aclent == NULL || statacl((char *)fname, STX_NORMAL, aclent, aclsize) < 0)
{
free(aclent);
return NULL;
@ -3399,7 +3419,11 @@ executable_file(char_u *name)
mch_can_exe(char_u *name, char_u **path, int use_path)
{
char_u *buf;
size_t bufsize;
size_t buflen;
char_u *p, *e;
char_u *p_end;
size_t elen;
int retval;
// When "use_path" is false and if it's an absolute or relative path don't
@ -3425,7 +3449,9 @@ mch_can_exe(char_u *name, char_u **path, int use_path)
p = (char_u *)getenv("PATH");
if (p == NULL || *p == NUL)
return -1;
buf = alloc(STRLEN(name) + STRLEN(p) + 2);
p_end = p + STRLEN(p);
bufsize = STRLEN(name) + (size_t)(p_end - p) + 2;
buf = alloc(bufsize);
if (buf == NULL)
return -1;
@ -3437,15 +3463,18 @@ mch_can_exe(char_u *name, char_u **path, int use_path)
{
e = (char_u *)strchr((char *)p, ':');
if (e == NULL)
e = p + STRLEN(p);
if (e - p <= 1) // empty entry means current dir
STRCPY(buf, "./");
else
e = p_end;
elen = (size_t)(e - p);
if (elen <= 1) // empty entry means current dir
{
vim_strncpy(buf, p, e - p);
add_pathsep(buf);
p = (char_u *)"./";
elen = STRLEN_LITERAL("./");
}
STRCAT(buf, name);
buflen = vim_snprintf((char *)buf, bufsize, "%.*s%s%s",
(int)elen,
p,
(after_pathsep(p, p + elen)) ? "" : PATHSEPSTR,
name);
retval = executable_file(buf);
if (retval == 1)
{
@ -3454,7 +3483,7 @@ mch_can_exe(char_u *name, char_u **path, int use_path)
if (buf[0] != '/')
*path = FullName_save(buf, TRUE);
else
*path = vim_strsave(buf);
*path = vim_strnsave(buf, buflen);
}
break;
}
@ -5233,13 +5262,13 @@ mch_call_shell_fork(
linenr_T lnum = curbuf->b_op_start.lnum;
int written = 0;
char_u *lp = ml_get(lnum);
size_t l;
size_t lplen = (size_t)ml_get_len(lnum);
close(fromshell_fd);
for (;;)
{
l = STRLEN(lp + written);
if (l == 0)
lplen -= written;
if (lplen == 0)
len = 0;
else if (lp[written] == NL)
// NL -> NUL translation
@ -5249,10 +5278,10 @@ mch_call_shell_fork(
char_u *s = vim_strchr(lp + written, NL);
len = write(toshell_fd, (char *)lp + written,
s == NULL ? l
s == NULL ? lplen
: (size_t)(s - (lp + written)));
}
if (len == (int)l)
if (len == (int)lplen)
{
// Finished a line, add a NL, unless this line
// should not have one.
@ -5272,6 +5301,7 @@ mch_call_shell_fork(
break;
}
lp = ml_get(lnum);
lplen = ml_get_len(lnum);
written = 0;
}
else if (len > 0)
@ -6089,14 +6119,14 @@ get_signal_name(int sig)
char_u numbuf[NUMBUFLEN];
if (sig == SIGKILL)
return vim_strsave((char_u *)"kill");
return vim_strnsave((char_u *)"kill", STRLEN_LITERAL("kill"));
for (i = 0; signal_info[i].sig != -1; i++)
if (sig == signal_info[i].sig)
return strlow_save((char_u *)signal_info[i].name);
vim_snprintf((char *)numbuf, NUMBUFLEN, "%d", sig);
return vim_strsave(numbuf);
i = vim_snprintf((char *)numbuf, NUMBUFLEN, "%d", sig);
return vim_strnsave(numbuf, i);
}
char *
@ -6852,7 +6882,9 @@ mch_expand_wildcards(
*/
int j;
char_u *tempname;
size_t tempnamelen;
char_u *command;
size_t commandlen;
FILE *fd;
char_u *buffer;
#define STYLE_ECHO 0 // use "echo", the default
@ -6866,10 +6898,14 @@ mch_expand_wildcards(
int check_spaces;
static int did_find_nul = FALSE;
int ampersand = FALSE;
#define STRING_INIT(s) \
{(char_u *)(s), STRLEN_LITERAL(s)}
// vimglob() function to define for Posix shell
static char *sh_vimglob_func = "vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >";
static string_T sh_vimglob_func = STRING_INIT("vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >");
// vimglob() function with globstar setting enabled, only for bash >= 4.X
static char *sh_globstar_opt = "[[ ${BASH_VERSINFO[0]} -ge 4 ]] && shopt -s globstar; ";
static string_T sh_globstar_opt = STRING_INIT("[[ ${BASH_VERSINFO[0]} -ge 4 ]] && shopt -s globstar; ");
#undef STRING_INIT
*num_file = 0; // default: no files found
*file = NULL;
@ -6943,12 +6979,12 @@ mch_expand_wildcards(
// Compute the length of the command. We need 2 extra bytes: for the
// optional '&' and for the NUL.
// Worst case: "unset nonomatch; print -N >" plus two is 29
len = STRLEN(tempname) + 29;
tempnamelen = STRLEN(tempname);
len = tempnamelen + 29;
if (shell_style == STYLE_VIMGLOB)
len += STRLEN(sh_vimglob_func);
len += sh_vimglob_func.length;
else if (shell_style == STYLE_GLOBSTAR)
len += STRLEN(sh_vimglob_func)
+ STRLEN(sh_globstar_opt);
len += sh_vimglob_func.length + sh_globstar_opt.length;
for (i = 0; i < num_pat; ++i)
{
@ -6985,63 +7021,62 @@ mch_expand_wildcards(
if (shell_style == STYLE_BT)
{
// change `command; command& ` to (command; command )
STRCPY(command, "(");
STRCAT(command, pat[0] + 1); // exclude first backtick
p = command + STRLEN(command) - 1;
*p-- = ')'; // remove last backtick
commandlen = vim_snprintf((char *)command, len, "(%s)>%s", pat[0] + 1, tempname); // +1 to exclude first backtick
p = (char_u *)strstr((char *)command, ")>");
if (p == NULL)
{
; // can't happen ;-)
}
else
{
--p;
while (p > command && VIM_ISWHITE(*p))
--p;
if (*p == '&') // remove trailing '&'
if (*p == '`') // remove backtick
*p = ' ';
--p;
while (p > command && VIM_ISWHITE(*p))
--p;
if (*p == '&') // remove ampersand
{
ampersand = TRUE;
*p = ' ';
}
STRCAT(command, ">");
}
}
else
{
STRCPY(command, "");
if (shell_style == STYLE_GLOB)
{
// Assume the nonomatch option is valid only for csh like shells,
// otherwise, this may set the positional parameters for the shell,
// e.g. "$*".
if (flags & EW_NOTFOUND)
STRCAT(command, "set nonomatch; ");
else
STRCAT(command, "unset nonomatch; ");
commandlen = vim_snprintf((char *)command, len, "%sset nonomatch; glob >%s",
(flags & EW_NOTFOUND) ? "" : "un", tempname);
}
if (shell_style == STYLE_GLOB)
STRCAT(command, "glob >");
else if (shell_style == STYLE_PRINT)
STRCAT(command, "print -N >");
commandlen = vim_snprintf((char *)command, len, "print -N >%s", tempname);
else if (shell_style == STYLE_VIMGLOB)
STRCAT(command, sh_vimglob_func);
commandlen = vim_snprintf((char *)command, len, "%s%s", sh_vimglob_func.string, tempname);
else if (shell_style == STYLE_GLOBSTAR)
{
STRCAT(command, sh_globstar_opt);
STRCAT(command, sh_vimglob_func);
}
commandlen = vim_snprintf((char *)command, len, "%s%s%s", sh_globstar_opt.string,
sh_vimglob_func.string, tempname);
else
STRCAT(command, "echo >");
}
commandlen = vim_snprintf((char *)command, len, "echo >%s", tempname);
STRCAT(command, tempname);
if (shell_style != STYLE_BT)
for (i = 0; i < num_pat; ++i)
{
// When using system() always add extra quotes, because the shell
// is started twice. Otherwise put a backslash before special
// characters, except inside ``.
#ifdef USE_SYSTEM
STRCAT(command, " \"");
STRCAT(command, pat[i]);
STRCAT(command, "\"");
commandlen += vim_snprintf((char *)command + commandlen, len, " \"%s\"", pat[i]);
#else
int intick = FALSE;
p = command + STRLEN(command);
p = command + commandlen;
*p++ = ' ';
for (j = 0; pat[i][j] != NUL; ++j)
{
@ -7070,12 +7105,14 @@ mch_expand_wildcards(
*p++ = pat[i][j];
}
*p = NUL;
commandlen = (size_t)(p - command);
#endif
}
}
if (flags & EW_SILENT)
show_shell_mess = FALSE;
if (ampersand)
STRCAT(command, "&"); // put the '&' after the redirection
STRCPY(command + commandlen, "&"); // put the '&' after the redirection
/*
* Using zsh -G: If a pattern has no matches, it is just deleted from
@ -8133,7 +8170,8 @@ do_xterm_trace(void)
char_u buf[50];
char_u *strp;
long got_hints;
static char_u *mouse_code;
static char_u *mouse_code = NULL;
static size_t mouse_codelen = 0;
static char_u mouse_name[2] = {KS_MOUSE, KE_FILLER};
static int prev_row = 0, prev_col = 0;
static XSizeHints xterm_hints;
@ -8156,6 +8194,8 @@ do_xterm_trace(void)
// Rely on the same mouse code for the duration of this
mouse_code = find_termcode(mouse_name);
if (mouse_code != NULL)
mouse_codelen = STRLEN(mouse_code);
prev_row = mouse_row;
prev_col = mouse_col;
xterm_trace = 2;
@ -8174,7 +8214,8 @@ do_xterm_trace(void)
xterm_hints.x = 2;
return TRUE;
}
if (mouse_code == NULL || STRLEN(mouse_code) > 45)
if (mouse_code == NULL || mouse_codelen > 45)
{
xterm_trace = 0;
return FALSE;
@ -8189,12 +8230,12 @@ do_xterm_trace(void)
return TRUE;
STRCPY(buf, mouse_code);
strp = buf + STRLEN(buf);
strp = buf + mouse_codelen;
*strp++ = (xterm_button | MOUSE_DRAG) & ~0x20;
*strp++ = (char_u)(col + ' ' + 1);
*strp++ = (char_u)(row + ' ' + 1);
*strp = 0;
add_to_input_buf(buf, STRLEN(buf));
*strp = NUL;
add_to_input_buf(buf, strp - buf);
prev_row = row;
prev_col = col;

View File

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