reckoner wrote: > Hi, > > When I try to complete using C-N or C-P in insert mode, I routinely get a > crash. I just download the latest svn ...snip... > and here is the call stack from VisualStudio 2008: > >> gvim.exe!ins_compl_add_infercase(unsigned char * str=0x0283a8d3, int >> len=1, int icase=1, unsigned char * fname=0x0285c118, int dir=1, int >> flags=0) Line 2280 + 0x18 bytes C > gvim.exe!ins_compl_files(int count=40, unsigned char * * > files=0x0285c1d0, int thesaurus=1, int flags=1, regmatch_T * > regmatch=0x0012f740, unsigned char * buf=0x0283a898, int * dir=0x0012f730) > Line 3062 + 0x29 bytes C > gvim.exe!ins_compl_dictionaries(unsigned char * > dict_start=0x0222d1fa, unsigned char * pat=0x028403e0, int flags=1, int > thesaurus=1) Line 2964 + 0x21 bytes C > gvim.exe!ins_compl_get_exp(pos_T * ini=0x007d6c0c) Line 4042 + 0xd2 > bytes C > gvim.exe!ins_compl_next(int allow_get_expansion=1, int count=1, int > insert_match=1) Line 4439 + 0xa bytes C > gvim.exe!ins_complete(int c=14) Line 5072 + 0x21 bytes C > gvim.exe!edit(int cmdchar=105, int startln=0, long count=1) Line > 1348 + 0x9 bytes C > gvim.exe!invoke_edit(cmdarg_S * cap=0x0012fb80, int repl=0, int > cmd=105, int startln=0) Line 8911 + 0x14 bytes C > gvim.exe!nv_edit(cmdarg_S * cap=0x0012fb80) Line 8884 + 0x14 bytes > C > gvim.exe!normal_cmd(oparg_S * oap=0x0012fc1c, int toplevel=1) Line > 1188 + 0x12 bytes C > gvim.exe!main_loop(int cmdwin=0, int noexmode=0) Line 1211 + 0xb > bytes C > gvim.exe!VimMain() Line 955 + 0x9 bytes C
I can also reproduce an invalid read & write memory access with Vim-7.3a (271a5907f944) with the thesaurus completion & 'infercase'. It happens when the word typed is longer than a completion match. Error is in the same function as where crash was reported: ins_compl_add_infercase(). ==8665== Invalid read of size 4 ==8665== at 0x8067252: ins_compl_add_infercase (edit.c:2282) ==8665== by 0x80684DF: ins_compl_files (edit.c:3060) ==8665== by 0x8068252: ins_compl_dictionaries (edit.c:2963) ==8665== by 0x8069DA8: ins_compl_get_exp (edit.c:4031) ==8665== by 0x806A993: ins_compl_next (edit.c:4439) ==8665== by 0x806BBDB: ins_complete (edit.c:5072) ==8665== by 0x8065CAC: edit (edit.c:1348) ==8665== by 0x812FEBA: invoke_edit (normal.c:8912) ==8665== by 0x812FE60: nv_edit (normal.c:8885) ==8665== by 0x8123AB7: normal_cmd (normal.c:1188) ==8665== by 0x80E71DC: main_loop (main.c:1216) ==8665== by 0x80E6CD3: main (main.c:960) ==8665== Address 0x4fe53dc is 0 bytes after a block of size 12 alloc'd ==8665== at 0x4024F70: malloc (vg_replace_malloc.c:236) ==8665== by 0x81144F6: lalloc (misc2.c:919) ==8665== by 0x8114413: alloc (misc2.c:818) ==8665== by 0x8066FBD: ins_compl_add_infercase (edit.c:2208) ==8665== by 0x80684DF: ins_compl_files (edit.c:3060) ==8665== by 0x8068252: ins_compl_dictionaries (edit.c:2963) ==8665== by 0x8069DA8: ins_compl_get_exp (edit.c:4031) ==8665== by 0x806A993: ins_compl_next (edit.c:4439) ==8665== by 0x806BBDB: ins_complete (edit.c:5072) ==8665== by 0x8065CAC: edit (edit.c:1348) ==8665== by 0x812FEBA: invoke_edit (normal.c:8912) ==8665== by 0x812FE60: nv_edit (normal.c:8885) (more errors after that) Steps to reproduce: 1) Download a thesaurus file: $ wget http://www.gutenberg.org/dirs/etext02/mthes10.zip $ unzip mthes10.zip Archive: mthes10.zip inflating: aaREADME.txt inflating: roget13a.txt inflating: mthesaur.txt 2) Run: $ valgrind vim -u NONE --noplugin \ -c 'set infercase ignorecase thesaurus=mthesaur.txt' \ -c 'call feedkeys("iEXAMPLE\<c-x>\<c-t>")' 2> vg.log 3) Observe errors in vg.log Attached patch fixes it. -- 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 271a5907f944 src/edit.c --- a/src/edit.c Tue May 25 22:09:21 2010 +0200 +++ b/src/edit.c Wed May 26 17:32:39 2010 +0200 @@ -2164,6 +2164,7 @@ int i, c; int actual_len; /* Take multi-byte characters */ int actual_compl_length; /* into account. */ + int min_len; int *wca; /* Wide character array. */ int has_lower = FALSE; int was_letter = FALSE; @@ -2204,6 +2205,11 @@ #endif actual_compl_length = compl_length; + /* actual_len may be smaller than actual_compl_length when + * using thesaurus */ + min_len = actual_len < actual_compl_length + ? actual_len : actual_compl_length; + /* Allocate wide character array for the completion and fill it. */ wca = (int *)alloc((unsigned)(actual_len * sizeof(int))); if (wca != NULL) @@ -2219,7 +2225,7 @@ /* Rule 1: Were any chars converted to lower? */ p = compl_orig_text; - for (i = 0; i < actual_compl_length; ++i) + for (i = 0; i < min_len; ++i) { #ifdef FEAT_MBYTE if (has_mbyte) @@ -2247,7 +2253,7 @@ if (!has_lower) { p = compl_orig_text; - for (i = 0; i < actual_compl_length; ++i) + for (i = 0; i < min_len; ++i) { #ifdef FEAT_MBYTE if (has_mbyte) @@ -2268,7 +2274,7 @@ /* Copy the original case of the part we typed. */ p = compl_orig_text; - for (i = 0; i < actual_compl_length; ++i) + for (i = 0; i < min_len; ++i) { #ifdef FEAT_MBYTE if (has_mbyte)