Hi

Using Vim-7.3.31, I observe the following error with Valgrind:

==5153== Invalid read of size 1
==5153==    at 0x811B075: mb_strnicmp (mbyte.c:3102)
==5153==    by 0x80871D0: eval4 (eval.c:4475)
==5153==    by 0x808737B: eval3 (eval.c:4157)
==5153==    by 0x80874AB: eval1 (eval.c:4086)
==5153==    by 0x808871C: eval0 (eval.c:3968)
==5153==    by 0x8088F99: eval_to_bool (eval.c:1271)
==5153==    by 0x80B17CD: ex_if (ex_eval.c:886)
==5153==    by 0x80AD486: do_one_cmd (ex_docmd.c:2656)
==5153==    by 0x80AB967: do_cmdline (ex_docmd.c:1122)
==5153==    by 0x808331C: call_user_func (eval.c:21960)
==5153==    by 0x8083D2E: call_func (eval.c:8291)
==5153==    by 0x8087883: get_func_tv (eval.c:8133)
==5153==    by 0x808CF00: ex_call (eval.c:3391)
==5153==    by 0x80AD486: do_one_cmd (ex_docmd.c:2656)
==5153==    by 0x80AB967: do_cmdline (ex_docmd.c:1122)
==5153==    by 0x8126C2E: nv_colon (normal.c:5319)
==5153==    by 0x8128B70: normal_cmd (normal.c:1190)
==5153==    by 0x80E59D6: main_loop (main.c:1260)
==5153==    by 0x80E8F90: main (main.c:965)
==5153==  Address 0x5143c47 is 3 bytes after a block of size 4 alloc'd
==5153==    at 0x4024F70: malloc (vg_replace_malloc.c:236)
==5153==    by 0x8110707: lalloc (misc2.c:919)
==5153==    by 0x81109B8: alloc (misc2.c:818)
==5153==    by 0x8111174: vim_strsave (misc2.c:1236)
==5153==    by 0x8075126: copy_tv (eval.c:19951)
==5153==    by 0x807578F: get_var_tv (eval.c:19017)
==5153==    by 0x8085E62: eval7 (eval.c:5096)
==5153==    by 0x80863D3: eval6 (eval.c:4734)
==5153==    by 0x808662B: eval5 (eval.c:4550)
==5153==    by 0x8086A09: eval4 (eval.c:4245)
==5153==    by 0x808737B: eval3 (eval.c:4157)
==5153==    by 0x80874AB: eval1 (eval.c:4086)
==5153==    by 0x808871C: eval0 (eval.c:3968)
==5153==    by 0x8088F99: eval_to_bool (eval.c:1271)
==5153==    by 0x80B17CD: ex_if (ex_eval.c:886)
==5153==    by 0x80AD486: do_one_cmd (ex_docmd.c:2656)
==5153==    by 0x80AB967: do_cmdline (ex_docmd.c:1122)
==5153==    by 0x808331C: call_user_func (eval.c:21960)
==5153==    by 0x8083D2E: call_func (eval.c:8291)
==5153==    by 0x8087883: get_func_tv (eval.c:8133)
==5153==    by 0x808CF00: ex_call (eval.c:3391)
==5153==    by 0x80AD486: do_one_cmd (ex_docmd.c:2656)
==5153==    by 0x80AB967: do_cmdline (ex_docmd.c:1122)
==5153==    by 0x8126C2E: nv_colon (normal.c:5319)
==5153==    by 0x8128B70: normal_cmd (normal.c:1190)
==5153==    by 0x80E59D6: main_loop (main.c:1260)
==5153==    by 0x80E8F90: main (main.c:965)
(and several more errors after that)

It happens when I use my LanguageTool plugin:

  http://www.vim.org/scripts/script.php?script_id=3223

After installing the plugin, I can reproduce the bug when
running Vim with Valgrind and doing this:

  :help change.txt
  :LanguageToolCheck

Then click in the buffer containing content of "change.txt"
and observe the valgrind error.

I see that mb_strnicmp(...) is called with input strings which
are not valid utf-8 strings.  Putting more debug printf, I see that
mb_strnicmp(...) is called with s1, s2 at eval.c:4476 with following
values:

[eval.c:4476] s1=[<80><FD><2E>] s2=[<80><FD><2C>] rettv->v_type=[2]
var2.v_type=[2]

Adding more debug printf, I see that the name of the variable containing
this invalid utf-8 sequence is "l:c".

This variable l:c is initialized in ~/.vim/plugin/LanguageTool.vim
as follows:

    call feedkeys("\<LeftMouse>")
    let l:c = getchar()

l:c contains <80><FD><2E> which is K_SPECIAL <FD><2E>

String contains a truncated utf-8 sequence (it's not a utf-8 string)
and causes mb_strnicmp(...) to access memory beyond end of string.

Attached patch makes mb_strnicmp() safer to prevent access beyond
end of string in case input strings contains truncated utf-8 sequences.

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
diff -r 758822790b43 src/mbyte.c
--- a/src/mbyte.c	Wed Oct 20 19:17:48 2010 +0200
+++ b/src/mbyte.c	Thu Oct 21 21:01:47 2010 +0200
@@ -3096,6 +3096,19 @@
     int		cdiff;
     int		incomplete = FALSE;
     int		n = (int)nn;
+    int		len1;
+    int		len2;
+    
+    if (enc_utf8)
+    {
+	/* Avoid access beyond EOS for truncated utf-8 sequences in s1 or s2 */
+	len1 = STRLEN(s1) + 1;
+	len2 = STRLEN(s2) + 1;
+	if (n > len1)
+	    n = len1;
+	if (n > len2)
+	    n = len2;
+    }
 
     for (i = 0; i < n; i += l)
     {

Raspunde prin e-mail lui