Patch 8.1.0993
Problem: ch_read() may return garbage if terminating NL is missing.
Solution: Add terminating NUL. (Ozaki Kiichi, closes #4065)
Files: src/channel.c, src/testdir/test_channel.vim
*** ../vim-8.1.0992/src/channel.c 2019-02-20 22:45:01.723613804 +0100
--- src/channel.c 2019-03-04 12:04:42.771564943 +0100
***************
*** 1797,1802 ****
--- 1797,1803 ----
mch_memmove(buf, buf + len, node->rq_buflen - len);
node->rq_buflen -= len;
+ node->rq_buffer[node->rq_buflen] = NUL;
}
/*
***************
*** 1819,1825 ****
return FAIL;
last_node = node->rq_next;
! len = node->rq_buflen + last_node->rq_buflen + 1;
if (want_nl)
while (last_node->rq_next != NULL
&& channel_first_nl(last_node) == NULL)
--- 1820,1826 ----
return FAIL;
last_node = node->rq_next;
! len = node->rq_buflen + last_node->rq_buflen;
if (want_nl)
while (last_node->rq_next != NULL
&& channel_first_nl(last_node) == NULL)
***************
*** 1828,1834 ****
len += last_node->rq_buflen;
}
! p = newbuf = alloc(len);
if (newbuf == NULL)
return FAIL; /* out of memory */
mch_memmove(p, node->rq_buffer, node->rq_buflen);
--- 1829,1835 ----
len += last_node->rq_buflen;
}
! p = newbuf = alloc(len + 1);
if (newbuf == NULL)
return FAIL; /* out of memory */
mch_memmove(p, node->rq_buffer, node->rq_buflen);
***************
*** 1842,1847 ****
--- 1843,1849 ----
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,2695 ****
}
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)
if (*p == NUL)
*p = NL;
! if (nl + 1 == buf + node->rq_buflen)
{
! /* get the whole buffer, drop the NL */
msg = channel_get(channel, part, NULL);
*nl = NUL;
}
--- 2668,2687 ----
}
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)
! {
! // 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
msg = channel_get(channel, part, NULL);
*nl = NUL;
}
*** ../vim-8.1.0992/src/testdir/test_channel.vim 2019-02-11
22:00:07.671917613 +0100
--- src/testdir/test_channel.vim 2019-03-04 12:01:07.813113919 +0100
***************
*** 203,210 ****
let start = reltime()
call assert_equal(v:none, ch_read(handle, {'timeout': 333}))
let elapsed = reltime(start)
! call assert_true(reltimefloat(elapsed) > 0.3)
! call assert_true(reltimefloat(elapsed) < 0.6)
" Send without waiting for a response, then wait for a response.
call ch_sendexpr(handle, 'wait a bit')
--- 203,209 ----
let start = reltime()
call assert_equal(v:none, ch_read(handle, {'timeout': 333}))
let elapsed = reltime(start)
! call assert_inrange(0.3, 0.6, reltimefloat(reltime(start)))
" Send without waiting for a response, then wait for a response.
call ch_sendexpr(handle, 'wait a bit')
***************
*** 434,442 ****
else
" Failed connection should wait about 500 msec. Can be longer if the
" computer is busy with other things.
! let elapsed = reltime(start)
! call assert_true(reltimefloat(elapsed) > 0.3)
! call assert_true(reltimefloat(elapsed) < 1.5)
endif
catch
if v:exception !~ 'Connection reset by peer'
--- 433,439 ----
else
" Failed connection should wait about 500 msec. Can be longer if the
" computer is busy with other things.
! call assert_inrange(0.3, 1.5, reltimefloat(reltime(start)))
endif
catch
if v:exception !~ 'Connection reset by peer'
***************
*** 1590,1597 ****
else
let elapsed = 1.0
endif
! call assert_true(elapsed > 0.5)
! call assert_true(elapsed < 1.0)
endfunc
"""""""""
--- 1587,1593 ----
else
let elapsed = 1.0
endif
! call assert_inrange(0.5, 1.0, elapsed)
endfunc
"""""""""
***************
*** 1764,1773 ****
bwipe!
endfunc
- func MyLineCountCb(ch, msg)
- let g:linecount += 1
- endfunc
-
func Test_read_nonl_line()
if !has('job')
return
--- 1760,1765 ----
***************
*** 1775,1782 ****
let g:linecount = 0
let arg = 'import sys;sys.stdout.write("1\n2\n3")'
! call job_start([s:python, '-c', arg], {'callback': 'MyLineCountCb'})
call WaitForAssert({-> assert_equal(3, g:linecount)})
endfunc
func Test_read_from_terminated_job()
--- 1767,1794 ----
let g:linecount = 0
let arg = 'import sys;sys.stdout.write("1\n2\n3")'
! call job_start([s:python, '-c', arg], {'callback': {-> execute('let
g:linecount += 1')}})
call WaitForAssert({-> assert_equal(3, g:linecount)})
+ unlet g:linecount
+ endfunc
+
+ func Test_read_nonl_in_close_cb()
+ if !has('job')
+ return
+ endif
+
+ func s:close_cb(ch)
+ while ch_status(a:ch) == 'buffered'
+ let g:out .= ch_read(a:ch)
+ endwhile
+ endfunc
+
+ let g:out = ''
+ let arg = 'import sys;sys.stdout.write("1\n2\n3")'
+ call job_start([s:python, '-c', arg], {'close_cb': function('s:close_cb')})
+ call WaitForAssert({-> assert_equal('123', g:out)})
+ unlet g:out
+ delfunc s:close_cb
endfunc
func Test_read_from_terminated_job()
***************
*** 1786,1793 ****
let g:linecount = 0
let arg = 'import os,sys;os.close(1);sys.stderr.write("test\n")'
! call job_start([s:python, '-c', arg], {'callback': 'MyLineCountCb'})
call WaitForAssert({-> assert_equal(1, g:linecount)})
endfunc
func Test_job_start_windows()
--- 1798,1806 ----
let g:linecount = 0
let arg = 'import os,sys;os.close(1);sys.stderr.write("test\n")'
! call job_start([s:python, '-c', arg], {'callback': {-> execute('let
g:linecount += 1')}})
call WaitForAssert({-> assert_equal(1, g:linecount)})
+ unlet g:linecount
endfunc
func Test_job_start_windows()
*** ../vim-8.1.0992/src/version.c 2019-03-04 11:40:06.274241644 +0100
--- src/version.c 2019-03-04 12:07:44.178258107 +0100
***************
*** 781,782 ****
--- 781,784 ----
{ /* Add new patch number below this line */
+ /**/
+ 993,
/**/
--
hundred-and-one symptoms of being an internet addict:
35. Your husband tells you he's had that beard for 2 months.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.