summaryrefslogtreecommitdiff
path: root/src/channel.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-03-04 12:09:49 +0100
committerBram Moolenaar <Bram@vim.org>2019-03-04 12:09:49 +0100
commit772153f8d85c83e08427d93460a676d7f079f002 (patch)
tree31248090660641a3d9bfd27eb32e6fd84ee53c95 /src/channel.c
parentcce713ddcc0c9ab29926c28e287cbb587a959b08 (diff)
downloadvim-git-772153f8d85c83e08427d93460a676d7f079f002.tar.gz
patch 8.1.0993: ch_read() may return garbage if terminating NL is missingv8.1.0993
Problem: ch_read() may return garbage if terminating NL is missing. Solution: Add terminating NUL. (Ozaki Kiichi, closes #4065)
Diffstat (limited to 'src/channel.c')
-rw-r--r--src/channel.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/src/channel.c b/src/channel.c
index a9e441139..176a3d7e1 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1797,6 +1797,7 @@ channel_consume(channel_T *channel, ch_part_T part, int len)
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_part_T part, int want_nl)
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_part_T part, int want_nl)
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_part_T part, int want_nl)
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, ch_part_T part)
}
buf = node->rq_buffer;
- 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;
- }
-
- /* Convert NUL to NL, the internal representation. */
- for (p = buf; p < nl && p < buf + node->rq_buflen; ++p)
+ // 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 + 1 == buf + node->rq_buflen)
+ if (nl == NULL)
+ {
+ // get the whole buffer, drop the NL
+ msg = channel_get(channel, part, NULL);
+ }
+ 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;
}