]> granicus.if.org Git - vim/commitdiff
patch 8.0.1372: profile log may be truncated halfway a character v8.0.1372
authorBram Moolenaar <Bram@vim.org>
Tue, 5 Dec 2017 15:46:28 +0000 (16:46 +0100)
committerBram Moolenaar <Bram@vim.org>
Tue, 5 Dec 2017 15:46:28 +0000 (16:46 +0100)
Problem:    Profile log may be truncated halfway a character.
Solution:   Find the start of the character. (Ozaki Kiichi, closes #2385)

src/ex_cmds2.c
src/testdir/test_profile.vim
src/version.c

index e2416057011e0dd7e39c683abecb4ac35c813b34..7b00ac265069be577976d94cc12f6924d3afb1f5 100644 (file)
@@ -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)
                    {
index ab39bcb644cd6bfa432b2ff87fe47b0a83ba7da2..ee617760f8105b39d748c92a3465e3e29529017e 100644 (file)
@@ -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
index 73b71d6f8ce354270c570108fb694984f01e88fb..3e8422954410df4c492061cbeda786cde3aa1733 100644 (file)
@@ -771,6 +771,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1372,
 /**/
     1371,
 /**/