Dominique wrote:
> Valgrind shows a write beyond end of string
> in Vim-7.4.2222 (huge) and older when doing:
>
> $ vim -u NONE -N -S bug-feedkeys-7.4.7222.vim 2> log
>
> ... where bug-feedkeys-7.4.7222.vim is the one-line
> attached file. Note that the file is in latin1 encoding
> and my locale is en_US.UTF-8.
>
> log file contains:
>
> ==4157== Memcheck, a memory error detector
> ==4157== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
> ==4157== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright
> info
> ==4157== Command: vim -u NONE -N -S bug-feedkeys-7.4.7222.vim
> ==4157==
> ==4157== Invalid write of size 1
> ==4157== at 0x4BB05F: vim_strsave_escape_csi (getchar.c:4695)
> ==4157== by 0x44DE8C: f_feedkeys (evalfunc.c:3126)
> ==4157== by 0x44A339: call_internal_func (evalfunc.c:997)
> ==4157== by 0x5E53E6: call_func (userfunc.c:1372)
> ==4157== by 0x5E319D: get_func_tv (userfunc.c:455)
> ==4157== by 0x5E8F70: ex_call (userfunc.c:2981)
> ==4157== by 0x47AC68: do_one_cmd (ex_docmd.c:2925)
> ==4157== by 0x477954: do_cmdline (ex_docmd.c:1110)
> ==4157== by 0x4755F8: do_source (ex_cmds2.c:4084)
> ==4157== by 0x474C0A: cmd_source (ex_cmds2.c:3697)
> ==4157== by 0x474B58: ex_source (ex_cmds2.c:3672)
> ==4157== by 0x47AC68: do_one_cmd (ex_docmd.c:2925)
> ==4157== Address 0xcd992d4 is 0 bytes after a block of size 4 alloc'd
> ==4157== at 0x4C2ABF5: malloc (vg_replace_malloc.c:299)
> ==4157== by 0x4F1427: lalloc (misc2.c:920)
> ==4157== by 0x4F12F4: alloc (misc2.c:818)
> ==4157== by 0x4BAE5B: vim_strsave_escape_csi (getchar.c:4662)
> ==4157== by 0x44DE8C: f_feedkeys (evalfunc.c:3126)
> ==4157== by 0x44A339: call_internal_func (evalfunc.c:997)
> ==4157== by 0x5E53E6: call_func (userfunc.c:1372)
> ==4157== by 0x5E319D: get_func_tv (userfunc.c:455)
> ==4157== by 0x5E8F70: ex_call (userfunc.c:2981)
> ==4157== by 0x47AC68: do_one_cmd (ex_docmd.c:2925)
> ==4157== by 0x477954: do_cmdline (ex_docmd.c:1110)
> ==4157== by 0x4755F8: do_source (ex_cmds2.c:4084)
> ==4157==
> ==4157== Invalid read of size 1
> ==4157== at 0x4C2DA04: strlen (vg_replace_strmem.c:454)
> ==4157== by 0x4B4FD2: ins_typebuf (getchar.c:979)
> ==4157== by 0x44DEDD: f_feedkeys (evalfunc.c:3129)
> ==4157== by 0x44A339: call_internal_func (evalfunc.c:997)
> ==4157== by 0x5E53E6: call_func (userfunc.c:1372)
> ==4157== by 0x5E319D: get_func_tv (userfunc.c:455)
> ==4157== by 0x5E8F70: ex_call (userfunc.c:2981)
> ==4157== by 0x47AC68: do_one_cmd (ex_docmd.c:2925)
> ==4157== by 0x477954: do_cmdline (ex_docmd.c:1110)
> ==4157== by 0x4755F8: do_source (ex_cmds2.c:4084)
> ==4157== by 0x474C0A: cmd_source (ex_cmds2.c:3697)
> ==4157== by 0x474B58: ex_source (ex_cmds2.c:3672)
> ==4157== Address 0xcd992d4 is 0 bytes after a block of size 4 alloc'd
> ==4157== at 0x4C2ABF5: malloc (vg_replace_malloc.c:299)
> ==4157== by 0x4F1427: lalloc (misc2.c:920)
> ==4157== by 0x4F12F4: alloc (misc2.c:818)
> ==4157== by 0x4BAE5B: vim_strsave_escape_csi (getchar.c:4662)
> ==4157== by 0x44DE8C: f_feedkeys (evalfunc.c:3126)
> ==4157== by 0x44A339: call_internal_func (evalfunc.c:997)
> ==4157== by 0x5E53E6: call_func (userfunc.c:1372)
> ==4157== by 0x5E319D: get_func_tv (userfunc.c:455)
> ==4157== by 0x5E8F70: ex_call (userfunc.c:2981)
> ==4157== by 0x47AC68: do_one_cmd (ex_docmd.c:2925)
> ==4157== by 0x477954: do_cmdline (ex_docmd.c:1110)
> ==4157== by 0x4755F8: do_source (ex_cmds2.c:4084)
>
> Code in getchar.c:
>
> 4654 char_u *
> 4655 vim_strsave_escape_csi(
> 4656 char_u *p)
> 4657 {
> 4658 char_u *res;
> 4659 char_u *s, *d;
> 4660
> 4661 /* Need a buffer to hold up to three times as much. */
> 4662 res = alloc((unsigned)(STRLEN(p) * 3) + 1);
> 4663 if (res != NULL)
> 4664 {
> 4665 d = res;
> 4666 for (s = p; *s != NUL; )
> 4667 {
> 4668 if (s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL)
> 4669 {
> 4670 /* Copy special key unmodified. */
> 4671 *d++ = *s++;
> 4672 *d++ = *s++;
> 4673 *d++ = *s++;
> 4674 }
> 4675 else
> 4676 {
> 4677 #ifdef FEAT_MBYTE
> 4678 int len = mb_char2len(PTR2CHAR(s));
> 4679 int len2 = mb_ptr2len(s);
> 4680 #endif
> 4681 /* Add character, possibly multi-byte to
> destination, escaping
> 4682 * CSI and K_SPECIAL. */
> 4683 d = add_char2buf(PTR2CHAR(s), d);
> 4684 #ifdef FEAT_MBYTE
> 4685 while (len < len2)
> 4686 {
> 4687 /* add following combining char */
> 4688 d = add_char2buf(PTR2CHAR(s + len), d);
> 4689 len += mb_char2len(PTR2CHAR(s + len));
> 4690 }
> 4691 #endif
> 4692 mb_ptr_adv(s);
> 4693 }
> 4694 }
> 4695 *d = NUL;
> 4696 }
> 4697 return res;
> 4698 }
>
> I see that vim_strsave_escape_csi() is invoked with
> p[0]=0xc0 p[1]=0x0 which is a truncated utf-8 string,
> or character À in latin1. Line 4688 calls add_char2buf(...)
> which will advance by 4 bytes, which goes beyond the
> end of buffer res (3 + 1 bytes) and then the line 4695
> writes beyond end of string.
Thanks for finding this. With some effort I managed to make a test that
exposes this problem when run under valgrind.
> I did not write a patch as I'm confused with this code:
> I'm surprised by the comment at line 4687 which
> says /* add following combining char */. From what I
> see, len2 does not include combining char, so the code
> does not add combining char. In fact, it looks like we
> always have len >= len2, and so condition at line 4685
> looks always false. We have len > len2 for invalid utf8
> sequences.
It looks OK to me, len2 is obtained with mb_ptr2len() which includes
composing characters. However, adding composing characters separately
seems pointless, they are handled the same way as base characters.
It's tricky. I think it's OK to reserve four output bytes for each
input byte. Please check that patch I'll send out.
--
How To Keep A Healthy Level Of Insanity:
16. Have your coworkers address you by your wrestling name, Rock Hard Kim.
/// 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.