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 {