mirror of
				https://github.com/vim/vim.git
				synced 2025-10-31 09:57:14 -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:
		
				
					committed by
					
						 Christian Brabandt
						Christian Brabandt
					
				
			
			
				
	
			
			
			
						parent
						
							f400a0cc41
						
					
				
				
					commit
					efc41a5958
				
			
							
								
								
									
										183
									
								
								src/os_unix.c
									
									
									
									
									
								
							
							
						
						
									
										183
									
								
								src/os_unix.c
									
									
									
									
									
								
							| @@ -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; | ||||
|   | ||||
| @@ -704,6 +704,8 @@ static char *(features[]) = | ||||
|  | ||||
| static int included_patches[] = | ||||
| {   /* Add new patch number below this line */ | ||||
| /**/ | ||||
|     1050, | ||||
| /**/ | ||||
|     1049, | ||||
| /**/ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user