diff src/channel.c @ 15975:915ed7ca92fa v8.1.0993

patch 8.1.0993: ch_read() may return garbage if terminating NL is missing commit https://github.com/vim/vim/commit/772153f8d85c83e08427d93460a676d7f079f002 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Mar 4 12:09:49 2019 +0100 patch 8.1.0993: ch_read() may return garbage if terminating NL is missing Problem: ch_read() may return garbage if terminating NL is missing. Solution: Add terminating NUL. (Ozaki Kiichi, closes https://github.com/vim/vim/issues/4065)
author Bram Moolenaar <Bram@vim.org>
date Mon, 04 Mar 2019 12:15:05 +0100
parents 379247470597
children 78faa25f9698
line wrap: on
line diff
--- a/src/channel.c
+++ b/src/channel.c
@@ -1797,6 +1797,7 @@ channel_consume(channel_T *channel, ch_p
 
     mch_memmove(buf, buf + len, node->rq_buflen - len);
     node->rq_buflen -= len;
+    node->rq_buffer[node->rq_buflen] = NUL;
 }
 
 /*
@@ -1819,7 +1820,7 @@ channel_collapse(channel_T *channel, ch_
 	return FAIL;
 
     last_node = node->rq_next;
-    len = node->rq_buflen + last_node->rq_buflen + 1;
+    len = node->rq_buflen + last_node->rq_buflen;
     if (want_nl)
 	while (last_node->rq_next != NULL
 		&& channel_first_nl(last_node) == NULL)
@@ -1828,7 +1829,7 @@ channel_collapse(channel_T *channel, ch_
 	    len += last_node->rq_buflen;
 	}
 
-    p = newbuf = alloc(len);
+    p = newbuf = alloc(len + 1);
     if (newbuf == NULL)
 	return FAIL;	    /* out of memory */
     mch_memmove(p, node->rq_buffer, node->rq_buflen);
@@ -1842,6 +1843,7 @@ channel_collapse(channel_T *channel, ch_
 	p += n->rq_buflen;
 	vim_free(n->rq_buffer);
     }
+    *p = NUL;
     node->rq_buflen = (long_u)(p - newbuf);
 
     /* dispose of the collapsed nodes and their buffers */
@@ -2666,30 +2668,20 @@ may_invoke_callback(channel_T *channel, 
 	    }
 	    buf = node->rq_buffer;
 
+	    // Convert NUL to NL, the internal representation.
+	    for (p = buf; (nl == NULL || p < nl)
+					    && p < buf + node->rq_buflen; ++p)
+		if (*p == NUL)
+		    *p = NL;
+
 	    if (nl == NULL)
 	    {
-		/* Flush remaining message that is missing a NL. */
-		char_u	*new_buf;
-
-		new_buf = vim_realloc(buf, node->rq_buflen + 1);
-		if (new_buf == NULL)
-		    /* This might fail over and over again, should the message
-		     * be dropped? */
-		    return FALSE;
-		buf = new_buf;
-		node->rq_buffer = buf;
-		nl = buf + node->rq_buflen++;
-		*nl = NUL;
+		// get the whole buffer, drop the NL
+		msg = channel_get(channel, part, NULL);
 	    }
-
-	    /* Convert NUL to NL, the internal representation. */
-	    for (p = buf; p < nl && p < buf + node->rq_buflen; ++p)
-		if (*p == NUL)
-		    *p = NL;
-
-	    if (nl + 1 == buf + node->rq_buflen)
+	    else if (nl + 1 == buf + node->rq_buflen)
 	    {
-		/* get the whole buffer, drop the NL */
+		// get the whole buffer
 		msg = channel_get(channel, part, NULL);
 		*nl = NUL;
 	    }