Valgrind memory checker detects access to uninitialized memory
when pressing <DEL> in REPLACE mode with utf-8 encoding:

==22362== Conditional jump or move depends on uninitialised value(s)
==22362==    at 0x8115406: utfc_ptr2len (mbyte.c:1709)
==22362==    by 0x80FF6DF: ins_bytes_len (misc1.c:1885)
==22362==    by 0x8068C83: mb_replace_pop_ins (edit.c:7070)
==22362==    by 0x8068BFC: replace_pop_ins (edit.c:7042)
==22362==    by 0x8068E87: replace_do_bs (edit.c:7172)
==22362==    by 0x806ADEF: ins_bs (edit.c:8559)
==22362==    by 0x805FB57: edit (edit.c:1057)
==22362==    by 0x8126035: invoke_edit (normal.c:8811)
==22362==    by 0x8123354: nv_Replace (normal.c:6930)
==22362==    by 0x8119D10: normal_cmd (normal.c:1152)
==22362==    by 0x80DE392: main_loop (main.c:1181)
==22362==    by 0x80DDEE2: main (main.c:940)
(this is only the first error, several other errors follow)

Bug is 100% reproducible.  Steps to reproduce it:

  1/ Start Vim with valgrind:

     $ valgrind vim -u NONE 2> valgrind.log

  2/ Enter INSERT mode and type a multi-byte character such as
     e acute accent for example with:  i<CTRL-k>e'

  2/ Enter REPLACE mode with:  <ESC>R

  3/ Type a character - to overwrite the previously typed e acute then
     press <DEL>:  -<DEL>

  4/ Observe than when pressing <DEL> valgrind gives error messages

I attach a test case that does exactly that, just run it with:

  $ valgrind vim -u NONE -s bug-del-replace-mode.vim 2> valgrind.log

Here is the code in misc1.c:

  1874     void
  1875 ins_bytes_len(p, len)
  1876     char_u      *p;
  1877     int         len;
  1878 {
  1879     int         i;
  1880 # ifdef FEAT_MBYTE
  1881     int         n;
  1882
  1883     for (i = 0; i < len; i += n)
  1884     {
!!1885         n = (*mb_ptr2len)(p + i);
  1886         ins_char_bytes(p + i, n);
  1887     }
  1888 # else
  1889     for (i = 0; i < len; ++i)
  1890         ins_char(p[i]);
  1891 # endif
  1892 }

Bug happens because string p (argument of ins_bytes_len) is not NUL
terminated (which is fine since length len is passed as argument) but
call to (*mb_ptr2len)(p + 1) a line 1885 expects a NUL terminated string
(hence bug).  So line 1885 actually accesses beyond p + len, which
is uninitialized.

Attached patch fixes it.

I'm using Vim-7.1.327 (huge) on Linux x86 with utf8 locale.

Regards
-- Dominique

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Attachment: bug-del-replace-mode.vim
Description: Binary data

Index: misc1.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/misc1.c,v
retrieving revision 1.80
diff -c -r1.80 misc1.c
*** misc1.c	25 Feb 2008 20:55:22 -0000	1.80
--- misc1.c	21 Jun 2008 13:19:40 -0000
***************
*** 1882,1888 ****
  
      for (i = 0; i < len; i += n)
      {
! 	n = (*mb_ptr2len)(p + i);
  	ins_char_bytes(p + i, n);
      }
  # else
--- 1882,1891 ----
  
      for (i = 0; i < len; i += n)
      {
! 	if (enc_utf8)
! 	    n = utfc_ptr2len_len(p + i, len - i);
! 	else
! 	    n = (*mb_ptr2len)(p + i);
  	ins_char_bytes(p + i, n);
      }
  # else

Raspunde prin e-mail lui