Hi

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.

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.

Bug was found using afl-fuzz.

Regards
Dominique

-- 
-- 
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.

Attachment: bug-feedkeys-7.4.7222.vim
Description: Binary data

Raspunde prin e-mail lui