Mercurial > vim
comparison 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 |
comparison
equal
deleted
inserted
replaced
15974:7d3d7e407216 | 15975:915ed7ca92fa |
---|---|
1795 readq_T *node = head->rq_next; | 1795 readq_T *node = head->rq_next; |
1796 char_u *buf = node->rq_buffer; | 1796 char_u *buf = node->rq_buffer; |
1797 | 1797 |
1798 mch_memmove(buf, buf + len, node->rq_buflen - len); | 1798 mch_memmove(buf, buf + len, node->rq_buflen - len); |
1799 node->rq_buflen -= len; | 1799 node->rq_buflen -= len; |
1800 node->rq_buffer[node->rq_buflen] = NUL; | |
1800 } | 1801 } |
1801 | 1802 |
1802 /* | 1803 /* |
1803 * Collapses the first and second buffer for "channel"/"part". | 1804 * Collapses the first and second buffer for "channel"/"part". |
1804 * Returns FAIL if that is not possible. | 1805 * Returns FAIL if that is not possible. |
1817 | 1818 |
1818 if (node == NULL || node->rq_next == NULL) | 1819 if (node == NULL || node->rq_next == NULL) |
1819 return FAIL; | 1820 return FAIL; |
1820 | 1821 |
1821 last_node = node->rq_next; | 1822 last_node = node->rq_next; |
1822 len = node->rq_buflen + last_node->rq_buflen + 1; | 1823 len = node->rq_buflen + last_node->rq_buflen; |
1823 if (want_nl) | 1824 if (want_nl) |
1824 while (last_node->rq_next != NULL | 1825 while (last_node->rq_next != NULL |
1825 && channel_first_nl(last_node) == NULL) | 1826 && channel_first_nl(last_node) == NULL) |
1826 { | 1827 { |
1827 last_node = last_node->rq_next; | 1828 last_node = last_node->rq_next; |
1828 len += last_node->rq_buflen; | 1829 len += last_node->rq_buflen; |
1829 } | 1830 } |
1830 | 1831 |
1831 p = newbuf = alloc(len); | 1832 p = newbuf = alloc(len + 1); |
1832 if (newbuf == NULL) | 1833 if (newbuf == NULL) |
1833 return FAIL; /* out of memory */ | 1834 return FAIL; /* out of memory */ |
1834 mch_memmove(p, node->rq_buffer, node->rq_buflen); | 1835 mch_memmove(p, node->rq_buffer, node->rq_buflen); |
1835 p += node->rq_buflen; | 1836 p += node->rq_buflen; |
1836 vim_free(node->rq_buffer); | 1837 vim_free(node->rq_buffer); |
1840 n = n->rq_next; | 1841 n = n->rq_next; |
1841 mch_memmove(p, n->rq_buffer, n->rq_buflen); | 1842 mch_memmove(p, n->rq_buffer, n->rq_buflen); |
1842 p += n->rq_buflen; | 1843 p += n->rq_buflen; |
1843 vim_free(n->rq_buffer); | 1844 vim_free(n->rq_buffer); |
1844 } | 1845 } |
1846 *p = NUL; | |
1845 node->rq_buflen = (long_u)(p - newbuf); | 1847 node->rq_buflen = (long_u)(p - newbuf); |
1846 | 1848 |
1847 /* dispose of the collapsed nodes and their buffers */ | 1849 /* dispose of the collapsed nodes and their buffers */ |
1848 for (n = node->rq_next; n != last_node; ) | 1850 for (n = node->rq_next; n != last_node; ) |
1849 { | 1851 { |
2664 return FALSE; /* incomplete message */ | 2666 return FALSE; /* incomplete message */ |
2665 } | 2667 } |
2666 } | 2668 } |
2667 buf = node->rq_buffer; | 2669 buf = node->rq_buffer; |
2668 | 2670 |
2669 if (nl == NULL) | 2671 // Convert NUL to NL, the internal representation. |
2670 { | 2672 for (p = buf; (nl == NULL || p < nl) |
2671 /* Flush remaining message that is missing a NL. */ | 2673 && p < buf + node->rq_buflen; ++p) |
2672 char_u *new_buf; | |
2673 | |
2674 new_buf = vim_realloc(buf, node->rq_buflen + 1); | |
2675 if (new_buf == NULL) | |
2676 /* This might fail over and over again, should the message | |
2677 * be dropped? */ | |
2678 return FALSE; | |
2679 buf = new_buf; | |
2680 node->rq_buffer = buf; | |
2681 nl = buf + node->rq_buflen++; | |
2682 *nl = NUL; | |
2683 } | |
2684 | |
2685 /* Convert NUL to NL, the internal representation. */ | |
2686 for (p = buf; p < nl && p < buf + node->rq_buflen; ++p) | |
2687 if (*p == NUL) | 2674 if (*p == NUL) |
2688 *p = NL; | 2675 *p = NL; |
2689 | 2676 |
2690 if (nl + 1 == buf + node->rq_buflen) | 2677 if (nl == NULL) |
2691 { | 2678 { |
2692 /* get the whole buffer, drop the NL */ | 2679 // get the whole buffer, drop the NL |
2680 msg = channel_get(channel, part, NULL); | |
2681 } | |
2682 else if (nl + 1 == buf + node->rq_buflen) | |
2683 { | |
2684 // get the whole buffer | |
2693 msg = channel_get(channel, part, NULL); | 2685 msg = channel_get(channel, part, NULL); |
2694 *nl = NUL; | 2686 *nl = NUL; |
2695 } | 2687 } |
2696 else | 2688 else |
2697 { | 2689 { |