diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-03-04 12:09:49 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-03-04 12:09:49 +0100 |
commit | 772153f8d85c83e08427d93460a676d7f079f002 (patch) | |
tree | 31248090660641a3d9bfd27eb32e6fd84ee53c95 /src/channel.c | |
parent | cce713ddcc0c9ab29926c28e287cbb587a959b08 (diff) | |
download | vim-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.c | 36 |
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; } |