changeset 12992:5532b5176870 v8.0.1372

patch 8.0.1372: profile log may be truncated halfway a character commit https://github.com/vim/vim/commit/ac112f01a6930c9d15cf0360b657373699916bfd Author: Bram Moolenaar <Bram@vim.org> Date: Tue Dec 5 16:46:28 2017 +0100 patch 8.0.1372: profile log may be truncated halfway a character Problem: Profile log may be truncated halfway a character. Solution: Find the start of the character. (Ozaki Kiichi, closes https://github.com/vim/vim/issues/2385)
author Christian Brabandt <cb@256bit.org>
date Tue, 05 Dec 2017 17:00:07 +0100
parents 0d7aa7f7b0aa
children 8a97cfc76c7e
files src/ex_cmds2.c src/testdir/test_profile.vim src/version.c
diffstat 3 files changed, 63 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1834,6 +1834,26 @@ script_dump_profile(FILE *fd)
 		{
 		    if (vim_fgets(IObuff, IOSIZE, sfd))
 			break;
+		    /* When a line has been truncated, append NL, taking care
+		     * of multi-byte characters . */
+		    if (IObuff[IOSIZE - 2] != NUL && IObuff[IOSIZE - 2] != NL)
+		    {
+			int n = IOSIZE - 2;
+# ifdef FEAT_MBYTE
+			if (enc_utf8)
+			{
+			    /* Move to the first byte of this char.
+			     * utf_head_off() doesn't work, because it checks
+			     * for a truncated character. */
+			    while (n > 0 && (IObuff[n] & 0xc0) == 0x80)
+				--n;
+			}
+			else if (has_mbyte)
+			    n -= mb_head_off(IObuff, IObuff + n);
+# endif
+			IObuff[n] = NL;
+			IObuff[n + 1] = NUL;
+		    }
 		    if (i < si->sn_prl_ga.ga_len
 				     && (pp = &PRL_ITEM(si, i))->snp_count > 0)
 		    {
--- a/src/testdir/test_profile.vim
+++ b/src/testdir/test_profile.vim
@@ -181,3 +181,44 @@ func Test_profile_errors()
   call assert_fails("profile pause", 'E750:')
   call assert_fails("profile continue", 'E750:')
 endfunc
+
+func Test_profile_truncate_mbyte()
+  if !has('multi_byte') || &enc !=# 'utf-8'
+    return
+  endif
+
+  let lines = [
+    \ 'scriptencoding utf-8',
+    \ 'func! Foo()',
+    \ '  return [',
+    \ '  \ "' . join(map(range(0x4E00, 0x4E00 + 340), 'nr2char(v:val)'), '') . '",',
+    \ '  \ "' . join(map(range(0x4F00, 0x4F00 + 340), 'nr2char(v:val)'), '') . '",',
+    \ '  \ ]',
+    \ 'endfunc',
+    \ 'call Foo()',
+    \ ]
+
+  call writefile(lines, 'Xprofile_file.vim')
+  call system(v:progpath
+    \ . ' -es --clean --cmd "set enc=utf-8"'
+    \ . ' -c "profile start Xprofile_file.log"'
+    \ . ' -c "profile file Xprofile_file.vim"'
+    \ . ' -c "so Xprofile_file.vim"'
+    \ . ' -c "qall!"')
+  call assert_equal(0, v:shell_error)
+
+  split Xprofile_file.log
+  if &fenc != ''
+    call assert_equal('utf-8', &fenc)
+  endif
+  /func! Foo()
+  let lnum = line('.')
+  call assert_match('^\s*return \[$', getline(lnum + 1))
+  call assert_match("\u4F52$", getline(lnum + 2))
+  call assert_match("\u5052$", getline(lnum + 3))
+  call assert_match('^\s*\\ \]$', getline(lnum + 4))
+  bwipe!
+
+  call delete('Xprofile_file.vim')
+  call delete('Xprofile_file.log')
+endfunc
--- a/src/version.c
+++ b/src/version.c
@@ -772,6 +772,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1372,
+/**/
     1371,
 /**/
     1370,