Dominique Pelle wrote:

> I've finally found the way to reproduce the crash
> in Vim-7.2.330 when using the Perforce-4.1 plugin.
> 
> Steps to reproduce the crash:
> 
> 1/ Install the Perforce-4.1 plugin:
> 
>   http://www.vim.org/scripts/script.php?script_id$0
> 
> 2/ Open a file which is in a Perforce repository which is
>   *not* yet checked-out.
> 
> 3/ Turn spelling checker on:
> 
>     :setlocal spell spelllang=en_us
>     :set spell
> 
> 4/ Put cursor on a misspelled word
> 
> 5/ Press  z=  to show spelling suggestions
> 
> 6/ Press  1<CR>  to select the first spelling suggestion.  You should see:
> 
>      Type number and <Enter> or click with mouse (empty cancels): 1
> 
> 7/ Perforce plugin then asks to checkout the file:
> 
>      Readonly file, do you want to checkout from perforce?
>      (Y)es, (N)o, [C]ancel:
> 
>   Press  Y  to checkout the file.
> 
> 8/ Perforce plugin then shows a message such as:
> 
>      foobar.txt#10 - opened for edit
>      ...snip...
>      Press ENTER or type command to continue
> 
>   Press <Enter> and observe the following error in Valgrind log
>   immediately after you press <Enter>.
> 
> 
> ==21106== Invalid read of size 1
> ==21106==    at 0x4C25350: strncpy (mc_replace_strmem.c:329)
> ==21106==    by 0x4DA0F0: vim_strnsave (misc2.c:1200)
> ==21106==    by 0x55AB6E: spell_suggest (spell.c:10433)
> ==21106==    by 0x4F1BAB: nv_zet (normal.c:5036)
> ==21106==    by 0x4EAF26: normal_cmd (normal.c:1188)
> ==21106==    by 0x4AA40B: main_loop (main.c:1211)
> ==21106==    by 0x4A9EF8: main (main.c:955)
> ==21106==  Address 0xbcecf1e is 3,838 bytes inside a block of size 4,096 
> free'd
> ==21106==    at 0x4C23D8C: free (vg_replace_malloc.c:325)
> ==21106==    by 0x4DAA26: vim_free (misc2.c:1647)
> ==21106==    by 0x4B82F0: mf_free_bhdr (memfile.c:991)
> ==21106==    by 0x4B7455: mf_close (memfile.c:262)
> ==21106==    by 0x4B9399: ml_close (memline.c:626)
> ==21106==    by 0x40F26A: buf_freeall (buffer.c:579)
> ==21106==    by 0x4568BA: do_ecmd (ex_cmds.c:3564)
> ==21106==    by 0x46E85D: do_exedit (ex_docmd.c:7577)
> ==21106==    by 0x46E4AD: ex_edit (ex_docmd.c:7473)
> ==21106==    by 0x466615: do_one_cmd (ex_docmd.c:2627)
> ==21106==    by 0x463D78: do_cmdline (ex_docmd.c:1096)
> ==21106==    by 0x44EDB1: call_user_func (eval.c:21301)
> ==21106==    by 0x43A9B2: call_func (eval.c:8123)
> ==21106==    by 0x43A5EC: get_func_tv (eval.c:7969)
> ==21106==    by 0x4339B8: ex_call (eval.c:3345)
> ==21106==    by 0x466615: do_one_cmd (ex_docmd.c:2627)
> ==21106==    by 0x463D78: do_cmdline (ex_docmd.c:1096)
> ==21106==    by 0x48ED95: apply_autocmds_group (fileio.c:9077)
> ==21106==    by 0x48E5F8: apply_autocmds (fileio.c:8686)
> ==21106==    by 0x4D0496: change_warning (misc1.c:2986)
> ==21106==    by 0x588707: u_savecommon (undo.c:371)
> ==21106==    by 0x5884EB: u_save (undo.c:241)
> ==21106==    by 0x588462: u_save_cursor (undo.c:218)
> ==21106==    by 0x55AB18: spell_suggest (spell.c:10425)
> ==21106==    by 0x4F1BAB: nv_zet (normal.c:5036)
> ==21106==    by 0x4EAF26: normal_cmd (normal.c:1188)
> ==21106==    by 0x4AA40B: main_loop (main.c:1211)
> ==21106==    by 0x4A9EF8: main (main.c:955)
> 
> (several more Valgrind errors follow after that...)
> 
> Notice that an autocommand was triggered at misc1.c:2986:
> 
> 2986  apply_autocmds(EVENT_FILECHANGEDRO, NULL, NULL, FALSE, curbuf);
> 
> The Perforce-4.1 plugin has set up the following 'FileChangeRO' autocommand:
> 
>  :au FileChangedRO
>  --- Auto-Commands ---
>  P4CheckOut  FileChangedRO
>      *         :call <SID>CheckOutFile()
> 
> 
> Autocommand is causing somehow memory (sug.su_badptr)
> to be freed in spell.c:10425 which is later used a few lines
> below in spell.c:10433:
> 
> spell.c:
> 
> !!10425 if (selected > 0 && selected <= sug.su_ga.ga_len &&
> u_save_cursor() == OK)
>  10426 {
>  10427     /* Save the from and to text for :spellrepall. */
>  10428     stp = &SUG(sug.su_ga, selected - 1);
>  10429     if (sug.su_badlen > stp->st_orglen)
>  10430     {
>  10431         /* Replacing less than "su_badlen", append the remainder to
>  10432          * repl_to. */
> !!10433         repl_from = vim_strnsave(sug.su_badptr, sug.su_badlen);
>  10434         vim_snprintf((char *)IObuff, IOSIZE, "%s%.*s", stp->st_word,
>  10435                 sug.su_badlen - stp->st_orglen,
>  10436                                           sug.su_badptr +
> stp->st_orglen);
>  10437         repl_to = vim_strsave(IObuff);
>  10438     }
> 
> 
> Attached patch fixes it. Please review it.
> 
> I also google-searched for a similar issue and found
> this post from the author of the Perforce plugin (in CC
> of this email), which was likely to be the same bug:
> 
> http://www.mail-archive.com/[email protected]/msg01909.html

Thanks for finding the problem and sending a fix.

There might be more places in the code that use the old buffer text,
while saving a line for undo may replace the buffer under our hands.
That's difficult to check for.

-- 
Contrary to popular belief, Unix is user friendly.
It just happens to be selective about who it makes friends with.
                                               -- Dave Parnas

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
-- 
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php

Raspunde prin e-mail lui