changeset 2768:c5e47b752f07 v7.3.160

updated for version 7.3.160 Problem: Unsafe string copying. Solution: Use vim_strncpy() instead of strcpy(). Use vim_strcat() instead of strcat().
author Bram Moolenaar <bram@vim.org>
date Mon, 11 Apr 2011 16:56:35 +0200
parents 9d6d058f0ebb
children ccce1db172b3
files src/buffer.c src/ex_docmd.c src/hardcopy.c src/menu.c src/misc1.c src/misc2.c src/netbeans.c src/os_unix.c src/proto/misc2.pro src/spell.c src/syntax.c src/tag.c src/version.c
diffstat 13 files changed, 64 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3176,7 +3176,7 @@ maketitle()
 	    /* format: "fname + (path) (1 of 2) - VIM" */
 
 	    if (curbuf->b_fname == NULL)
-		STRCPY(buf, _("[No Name]"));
+		vim_strncpy(buf, (char_u *)_("[No Name]"), IOSIZE - 100);
 	    else
 	    {
 		p = transstr(gettail(curbuf->b_fname));
@@ -3232,7 +3232,7 @@ maketitle()
 	    if (serverName != NULL)
 	    {
 		STRCAT(buf, " - ");
-		STRCAT(buf, serverName);
+		vim_strcat(buf, serverName, IOSIZE);
 	    }
 	    else
 #endif
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -5096,7 +5096,9 @@ check_more(message, forceit)
 		char_u	buff[IOSIZE];
 
 		if (n == 1)
-		    STRCPY(buff, _("1 more file to edit.  Quit anyway?"));
+		    vim_strncpy(buff,
+			    (char_u *)_("1 more file to edit.  Quit anyway?"),
+								  IOSIZE - 1);
 		else
 		    vim_snprintf((char *)buff, IOSIZE,
 			      _("%d more files to edit.  Quit anyway?"), n);
--- a/src/hardcopy.c
+++ b/src/hardcopy.c
@@ -1761,12 +1761,12 @@ prt_find_resource(name, resource)
 {
     char_u	buffer[MAXPATHL + 1];
 
-    STRCPY(resource->name, name);
+    vim_strncpy(resource->name, (char_u *)name, 63);
     /* Look for named resource file in runtimepath */
     STRCPY(buffer, "print");
     add_pathsep(buffer);
-    STRCAT(buffer, name);
-    STRCAT(buffer, ".ps");
+    vim_strcat(buffer, (char_u *)name, MAXPATHL);
+    vim_strcat(buffer, (char_u *)".ps", MAXPATHL);
     resource->filename[0] = NUL;
     return (do_in_runtimepath(buffer, FALSE, prt_resource_name,
 							   resource->filename)
--- a/src/menu.c
+++ b/src/menu.c
@@ -1394,7 +1394,8 @@ get_menu_names(xp, idx)
     int		idx;
 {
     static vimmenu_T	*menu = NULL;
-    static char_u	tbuffer[256]; /*hack*/
+#define TBUFFER_LEN 256
+    static char_u	tbuffer[TBUFFER_LEN]; /*hack*/
     char_u		*str;
 #ifdef FEAT_MULTI_LANG
     static  int		should_advance = FALSE;
@@ -1428,11 +1429,11 @@ get_menu_names(xp, idx)
 	{
 #ifdef FEAT_MULTI_LANG
 	    if (should_advance)
-		STRCPY(tbuffer, menu->en_dname);
+		vim_strncpy(tbuffer, menu->en_dname, TBUFFER_LEN - 2);
 	    else
 	    {
 #endif
-		STRCPY(tbuffer, menu->dname);
+		vim_strncpy(tbuffer, menu->dname,  TBUFFER_LEN - 2);
 #ifdef FEAT_MULTI_LANG
 		if (menu->en_dname == NULL)
 		    should_advance = TRUE;
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -3332,19 +3332,23 @@ msgmore(n)
 	if (pn == 1)
 	{
 	    if (n > 0)
-		STRCPY(msg_buf, _("1 more line"));
+		vim_strncpy(msg_buf, (char_u *)_("1 more line"),
+							     MSG_BUF_LEN - 1);
 	    else
-		STRCPY(msg_buf, _("1 line less"));
+		vim_strncpy(msg_buf, (char_u *)_("1 line less"),
+							     MSG_BUF_LEN - 1);
 	}
 	else
 	{
 	    if (n > 0)
-		sprintf((char *)msg_buf, _("%ld more lines"), pn);
+		vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
+						     _("%ld more lines"), pn);
 	    else
-		sprintf((char *)msg_buf, _("%ld fewer lines"), pn);
+		vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
+						    _("%ld fewer lines"), pn);
 	}
 	if (got_int)
-	    STRCAT(msg_buf, _(" (Interrupted)"));
+	    vim_strcat(msg_buf, (char_u *)_(" (Interrupted)"), MSG_BUF_LEN);
 	if (msg(msg_buf))
 	{
 	    set_keep_msg(msg_buf, 0);
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1647,6 +1647,28 @@ vim_strncpy(to, from, len)
 }
 
 /*
+ * Like strcat(), but make sure the result fits in "tosize" bytes and is
+ * always NUL terminated.
+ */
+    void
+vim_strcat(to, from, tosize)
+    char_u	*to;
+    char_u	*from;
+    size_t	tosize;
+{
+    size_t tolen = STRLEN(to);
+    size_t fromlen = STRLEN(from);
+
+    if (tolen + fromlen + 1 > tosize)
+    {
+	mch_memmove(to + tolen, from, tosize - tolen - 1);
+	to[tosize - 1] = NUL;
+    }
+    else
+	STRCPY(to + tolen, from);
+}
+
+/*
  * Isolate one part of a string option where parts are separated with
  * "sep_chars".
  * The part is copied into "buf[maxlen]".
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -3914,14 +3914,12 @@ print_save_msg(buf, nchars)
     }
     else
     {
-	char_u ebuf[BUFSIZ];
-
-	STRCPY(ebuf, (char_u *)_("E505: "));
-	STRCAT(ebuf, IObuff);
-	STRCAT(ebuf, (char_u *)_("is read-only (add ! to override)"));
-	STRCPY(IObuff, ebuf);
-	nbdebug(("    %s\n", ebuf ));
-	emsg(IObuff);
+	char_u msgbuf[IOSIZE];
+
+	vim_snprintf((char *)msgbuf, IOSIZE,
+		_("E505: %s is read-only (add ! to override)"), IObuff);
+	nbdebug(("    %s\n", msgbuf));
+	emsg(msgbuf);
     }
 }
 
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -5725,6 +5725,7 @@ mch_expand_wildcards(num_pat, pat, num_f
 	if (shell_style == STYLE_PRINT && !did_find_nul)
 	{
 	    /* If there is a NUL, set did_find_nul, else set check_spaces */
+	    buffer[len] = NUL;
 	    if (len && (int)STRLEN(buffer) < (int)len - 1)
 		did_find_nul = TRUE;
 	    else
@@ -6594,7 +6595,7 @@ do_xterm_trace()
 	    xterm_hints.x = 2;
 	return TRUE;
     }
-    if (mouse_code == NULL)
+    if (mouse_code == NULL || STRLEN(mouse_code) > 45)
     {
 	xterm_trace = 0;
 	return FALSE;
--- a/src/proto/misc2.pro
+++ b/src/proto/misc2.pro
@@ -40,6 +40,7 @@ void copy_spaces __ARGS((char_u *ptr, si
 void copy_chars __ARGS((char_u *ptr, size_t count, int c));
 void del_trailing_spaces __ARGS((char_u *ptr));
 void vim_strncpy __ARGS((char_u *to, char_u *from, size_t len));
+void vim_strcat __ARGS((char_u *to, char_u *from, size_t tosize));
 int copy_option_part __ARGS((char_u **option, char_u *buf, int maxlen, char *sep_chars));
 void vim_free __ARGS((void *x));
 int vim_stricmp __ARGS((char *s1, char *s2));
--- a/src/spell.c
+++ b/src/spell.c
@@ -6957,7 +6957,7 @@ store_aff_word(spin, word, afflist, affi
 			    if (ae->ae_add == NULL)
 				*newword = NUL;
 			    else
-				STRCPY(newword, ae->ae_add);
+				vim_strncpy(newword, ae->ae_add, MAXWLEN - 1);
 			    p = word;
 			    if (ae->ae_chop != NULL)
 			    {
@@ -6978,7 +6978,7 @@ store_aff_word(spin, word, afflist, affi
 			else
 			{
 			    /* suffix: chop/add at the end of the word */
-			    STRCPY(newword, word);
+			    vim_strncpy(newword, word, MAXWLEN - 1);
 			    if (ae->ae_chop != NULL)
 			    {
 				/* Remove chop string. */
@@ -8654,7 +8654,7 @@ spell_make_sugfile(spin, wfname)
      * Write the .sug file.
      * Make the file name by changing ".spl" to ".sug".
      */
-    STRCPY(fname, wfname);
+    vim_strncpy(fname, wfname, MAXPATHL - 1);
     len = (int)STRLEN(fname);
     fname[len - 2] = 'u';
     fname[len - 1] = 'g';
@@ -10261,7 +10261,7 @@ spell_suggest(count)
 
 	    /* The suggested word may replace only part of the bad word, add
 	     * the not replaced part. */
-	    STRCPY(wcopy, stp->st_word);
+	    vim_strncpy(wcopy, stp->st_word, MAXWLEN);
 	    if (sug.su_badlen > stp->st_orglen)
 		vim_strncpy(wcopy + stp->st_wordlen,
 					       sug.su_badptr + stp->st_orglen,
@@ -13162,7 +13162,7 @@ stp_sal_score(stp, su, slang, badsound)
 	pbad = badsound2;
     }
 
-    if (lendiff > 0)
+    if (lendiff > 0 && stp->st_wordlen + lendiff < MAXWLEN)
     {
 	/* Add part of the bad word to the good word, so that we soundfold
 	 * what replaces the bad word. */
@@ -13875,7 +13875,7 @@ check_suggestions(su, gap)
     for (i = gap->ga_len - 1; i >= 0; --i)
     {
 	/* Need to append what follows to check for "the the". */
-	STRCPY(longword, stp[i].st_word);
+	vim_strncpy(longword, stp[i].st_word, MAXWLEN);
 	len = stp[i].st_wordlen;
 	vim_strncpy(longword + len, su->su_badptr + stp[i].st_orglen,
 							       MAXWLEN - len);
@@ -14221,7 +14221,7 @@ spell_soundfold_sal(slang, inword, res)
 	*t = NUL;
     }
     else
-	STRCPY(word, s);
+	vim_strncpy(word, s, MAXWLEN - 1);
 
     smp = (salitem_T *)slang->sl_sal.ga_data;
 
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -8576,8 +8576,8 @@ highlight_list_arg(id, didh, type, iarg,
 		if (iarg & hl_attr_table[i])
 		{
 		    if (buf[0] != NUL)
-			STRCAT(buf, ",");
-		    STRCAT(buf, hl_name_table[i]);
+			vim_strcat(buf, (char_u *)",", 100);
+		    vim_strcat(buf, (char_u *)hl_name_table[i], 100);
 		    iarg &= ~hl_attr_table[i];	    /* don't want "inverse" */
 		}
 	    }
--- a/src/tag.c
+++ b/src/tag.c
@@ -806,7 +806,7 @@ do_tag(tag, type, count, forceit, verbos
 		    p = tag_full_fname(&tagp);
 		    if (p == NULL)
 			continue;
-		    STRCPY(fname, p);
+		    vim_strncpy(fname, p, MAXPATHL);
 		    vim_free(p);
 
 		    /*
--- a/src/version.c
+++ b/src/version.c
@@ -715,6 +715,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    160,
+/**/
     159,
 /**/
     158,