changeset 3277:55cebc7e5de0 v7.3.407

updated for version 7.3.407 Problem: ":12verbose call F()" may duplicate text while trying to truncate. (Thinca) Solution: Only truncate when there is not enough room. Also check the byte length of the buffer.
author Bram Moolenaar <bram@vim.org>
date Fri, 20 Jan 2012 20:44:43 +0100
parents 98958001bcfb
children 6d1e3108a03f
files src/buffer.c src/eval.c src/ex_getln.c src/message.c src/proto/message.pro src/version.c
diffstat 6 files changed, 41 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -3258,9 +3258,8 @@ maketitle()
 	    if (maxlen > 0)
 	    {
 		/* make it shorter by removing a bit in the middle */
-		len = vim_strsize(buf);
-		if (len > maxlen)
-		    trunc_string(buf, buf, maxlen);
+		if (vim_strsize(buf) > maxlen)
+		    trunc_string(buf, buf, maxlen, IOSIZE);
 	    }
 	}
     }
--- a/src/eval.c
+++ b/src/eval.c
@@ -22163,8 +22163,12 @@ call_user_func(fp, argcount, argvars, re
 			s = tv2string(&argvars[i], &tofree, numbuf2, 0);
 			if (s != NULL)
 			{
-			    trunc_string(s, buf, MSG_BUF_CLEN);
-			    msg_puts(buf);
+			    if (vim_strsize(s) > MSG_BUF_CLEN)
+			    {
+				trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
+				s = buf;
+			    }
+			    msg_puts(s);
 			    vim_free(tofree);
 			}
 		    }
@@ -22252,8 +22256,12 @@ call_user_func(fp, argcount, argvars, re
 	    s = tv2string(fc->rettv, &tofree, numbuf2, 0);
 	    if (s != NULL)
 	    {
-		trunc_string(s, buf, MSG_BUF_CLEN);
-		smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
+		if (vim_strsize(s) > MSG_BUF_CLEN)
+		{
+		    trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
+		    s = buf;
+		}
+		smsg((char_u *)_("%s returning %s"), sourcing_name, s);
 		vim_free(tofree);
 	    }
 	}
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -5923,7 +5923,7 @@ ex_history(eap)
 							      hist[i].hisnum);
 		    if (vim_strsize(hist[i].hisstr) > (int)Columns - 10)
 			trunc_string(hist[i].hisstr, IObuff + STRLEN(IObuff),
-							   (int)Columns - 10);
+				  (int)Columns - 10, IOSIZE - STRLEN(IObuff));
 		    else
 			STRCAT(IObuff, hist[i].hisstr);
 		    msg_outtrans(IObuff);
--- a/src/message.c
+++ b/src/message.c
@@ -222,15 +222,16 @@ msg_strtrunc(s, force)
 	    if (enc_utf8)
 		/* may have up to 18 bytes per cell (6 per char, up to two
 		 * composing chars) */
-		buf = alloc((room + 2) * 18);
+		len = (room + 2) * 18;
 	    else if (enc_dbcs == DBCS_JPNU)
 		/* may have up to 2 bytes per cell for euc-jp */
-		buf = alloc((room + 2) * 2);
+		len = (room + 2) * 2;
 	    else
 #endif
-		buf = alloc(room + 2);
+		len = room + 2;
+	    buf = alloc(len);
 	    if (buf != NULL)
-		trunc_string(s, buf, room);
+		trunc_string(s, buf, room, len);
 	}
     }
     return buf;
@@ -241,10 +242,11 @@ msg_strtrunc(s, force)
  * "s" and "buf" may be equal.
  */
     void
-trunc_string(s, buf, room)
+trunc_string(s, buf, room, buflen)
     char_u	*s;
     char_u	*buf;
     int		room;
+    int		buflen;
 {
     int		half;
     int		len;
@@ -257,7 +259,7 @@ trunc_string(s, buf, room)
     len = 0;
 
     /* First part: Start of the string. */
-    for (e = 0; len < half; ++e)
+    for (e = 0; len < half && e < buflen; ++e)
     {
 	if (s[e] == NUL)
 	{
@@ -274,7 +276,8 @@ trunc_string(s, buf, room)
 	if (has_mbyte)
 	    for (n = (*mb_ptr2len)(s + e); --n > 0; )
 	    {
-		++e;
+		if (++e == buflen)
+		    break;
 		buf[e] = s[e];
 	    }
 #endif
@@ -319,8 +322,19 @@ trunc_string(s, buf, room)
     }
 
     /* Set the middle and copy the last part. */
-    mch_memmove(buf + e, "...", (size_t)3);
-    STRMOVE(buf + e + 3, s + i);
+    if (e + 3 < buflen)
+    {
+	mch_memmove(buf + e, "...", (size_t)3);
+	len = STRLEN(s + i) + 1;
+	if (len >= buflen - e - 3)
+	    len = buflen - e - 3 - 1;
+	mch_memmove(buf + e + 3, s + i, len);
+	buf[e + 3 + len - 1] = NUL;
+    }
+    else
+    {
+	buf[e - 1] = NUL;  // make sure it is truncated
+    }
 }
 
 /*
--- a/src/proto/message.pro
+++ b/src/proto/message.pro
@@ -4,7 +4,7 @@ int verb_msg __ARGS((char_u *s));
 int msg_attr __ARGS((char_u *s, int attr));
 int msg_attr_keep __ARGS((char_u *s, int attr, int keep));
 char_u *msg_strtrunc __ARGS((char_u *s, int force));
-void trunc_string __ARGS((char_u *s, char_u *buf, int room));
+void trunc_string __ARGS((char_u *s, char_u *buf, int room, int buflen));
 void reset_last_sourcing __ARGS((void));
 void msg_source __ARGS((int attr));
 int emsg_not_now __ARGS((void));
--- 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 */
 /**/
+    407,
+/**/
     406,
 /**/
     405,