Bram Moolenaar wrote:
> Thanks for the patch. I thought of catching the problem at the cause,
> by disallowing the autocommands to do something that will cause trouble.
> However, it's very difficult to catch all situations.
>
> So I think we can do both: disallow autocommands to do things that are
> clearly wrong, and give an error if we notice side effects. That should
> be safe.
>
> Please have a look at the patch below. There might still be other
> autocommands that cause trouble. If you see one, please report.
...snip...
I applied your patch to Vim-7.2.128.
I still observe something wrong after patching (something
which I did not think of testing earlier, so the problem
I see in your patch was also in my patch).
The bug I see only happens when opening a file in Vim
which does not exist but for which there is a swap file.
Steps to reproduce it:
# Open a file foobar (which does not exist) in vim to create
# swap file .foobar.swp
$ rm -f ~/foobar
$ vim ~/foobar
# In another terminal...
$ vim -u NONE
:au! SwapExists * cd /tmp
:e ~/foobar
The following prompt shows up:
Swap file "~/.foobar.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort:
Press e.
Valgrind then outputs the following error
==17742== Invalid read of size 1
==17742== at 0x810B4DA: get_past_head (misc1.c:4472)
==17742== by 0x810B428: gettail_sep (misc1.c:4419)
==17742== by 0x810B610: dir_of_file_exists (misc1.c:4582)
==17742== by 0x80C13CD: readfile (fileio.c:606)
==17742== by 0x8052D8E: open_buffer (buffer.c:130)
==17742== by 0x8097AC3: do_ecmd (ex_cmds.c:3655)
==17742== by 0x80ADE20: do_exedit (ex_docmd.c:7557)
==17742== by 0x80ADA97: ex_edit (ex_docmd.c:7452)
==17742== by 0x80A6517: do_one_cmd (ex_docmd.c:2622)
==17742== by 0x80A3D97: do_cmdline (ex_docmd.c:1096)
==17742== by 0x8129422: nv_colon (normal.c:5218)
==17742== by 0x8122A86: normal_cmd (normal.c:1189)
==17742== by 0x80E5F8D: main_loop (main.c:1180)
==17742== by 0x80E5ADA: main (main.c:939)
==17742== Address 0x4d34be0 is 0 bytes inside a block of size 15 free'd
==17742== at 0x4024E5A: free (vg_replace_malloc.c:323)
==17742== by 0x8113C72: vim_free (misc2.c:1631)
==17742== by 0x80C8E58: shorten_fnames (fileio.c:5743)
==17742== by 0x80AE6AA: ex_cd (ex_docmd.c:7939)
==17742== by 0x80A6517: do_one_cmd (ex_docmd.c:2622)
==17742== by 0x80A3D97: do_cmdline (ex_docmd.c:1096)
==17742== by 0x80CC9A5: apply_autocmds_group (fileio.c:8883)
==17742== by 0x80CC3A8: apply_autocmds (fileio.c:8494)
==17742== by 0x80F9592: do_swapexists (memline.c:3770)
==17742== by 0x80F9EAD: findswapname (memline.c:4130)
==17742== by 0x80F3FF8: ml_open_file (memline.c:553)
==17742== by 0x80F411E: check_need_swap (memline.c:605)
==17742== by 0x80C13BF: readfile (fileio.c:605)
==17742== by 0x8052D8E: open_buffer (buffer.c:130)
==17742== by 0x8097AC3: do_ecmd (ex_cmds.c:3655)
==17742== by 0x80ADE20: do_exedit (ex_docmd.c:7557)
==17742== by 0x80ADA97: ex_edit (ex_docmd.c:7452)
==17742== by 0x80A6517: do_one_cmd (ex_docmd.c:2622)
==17742== by 0x80A3D97: do_cmdline (ex_docmd.c:1096)
==17742== by 0x8129422: nv_colon (normal.c:5218)
==17742== by 0x8122A86: normal_cmd (normal.c:1189)
==17742== by 0x80E5F8D: main_loop (main.c:1180)
==17742== by 0x80E5ADA: main (main.c:939)
(and several other errors follow)
If I enter ":messages" I also do not see the error
message E812 (I would expect to see this message).
I do not see this issue when the file foobar already exists.
This remaining issue happens because call to
check_need_swap() in fileio.c:605 (or line 592 in
pristine vim-7.2.128) may trigger an autocommand
which can also invalidate fname.
Attached patch (on top of your patch) fixes this
remaining issue (and a typo). I will continue to test
with this patch for a while but so far it looks OK.
I can't see any further bugs so far with autocommands.
Regards
Dominique
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---
*** fileio.c.old_patch 2009-03-01 10:08:48.000000000 +0100
--- fileio.c 2009-03-01 10:15:24.000000000 +0100
***************
*** 298,304 ****
#ifdef FEAT_AUTOCMD
/* Remember the initial values of curbuf, curbuf->b_ffname and
* curbuf->b_fname to detect whether they are altered as a result of
! * executing nasaty autocommands. Also check if "fname" and "sfname"
* point to one of these values. */
buf_T *old_curbuf = curbuf;
char_u *old_b_ffname = curbuf->b_ffname;
--- 298,304 ----
#ifdef FEAT_AUTOCMD
/* Remember the initial values of curbuf, curbuf->b_ffname and
* curbuf->b_fname to detect whether they are altered as a result of
! * executing nasty autocommands. Also check if "fname" and "sfname"
* point to one of these values. */
buf_T *old_curbuf = curbuf;
char_u *old_b_ffname = curbuf->b_ffname;
***************
*** 602,608 ****
--- 602,620 ----
#ifdef FEAT_QUICKFIX
if (!bt_dontwrite(curbuf))
#endif
+ {
check_need_swap(newfile);
+ #ifdef FEAT_AUTOCMD
+ /* check_need_swap may have triggered autocommand SwapExists */
+ if (curbuf != old_curbuf
+ || (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
+ || (using_b_fname && (old_b_fname != curbuf->b_fname)))
+ {
+ EMSG(_("E812: Autocommands changed buffer or buffer name"));
+ return FAIL;
+ }
+ #endif
+ }
if (dir_of_file_exists(fname))
filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
else