Hi

When the argument of the commands :diffget or :diffput
results in the same buffer as the current buffer, the command
corrupts the content of the current buffer.

Steps to reproduce:

1/ create 2 sample files

$ echo foo > file1
$ echo bar > file2

2/ run vim in diff mode

$ vim -u NONE -d file1 file2

3/ While in file1, run the command
      :diffget 1

Notice that argument "1" reffers buffer of file1 (i.e. current buffer)
so I would expect diffget to do nothing.  Instead I observe that if
deletes the content of the diff chunk.  Only "diffget 2" would make
sense here. In some more complex cases, it creates garbage in
the current buffer.

Valgrind memory checker also detects errors at step 3/ in the
case of diffget command:

==11910== Conditional jump or move depends on uninitialised value(s)
==11910==    at 0x80CC2A2: aucmd_restbuf (fileio.c:8405)
==11910==    by 0x80626D9: ex_diffgetput (diff.c:2348)
==11910==    by 0x80A679B: do_one_cmd (ex_docmd.c:2622)
==11910==    by 0x80A401B: do_cmdline (ex_docmd.c:1096)
==11910==    by 0x8129708: nv_colon (normal.c:5233)
==11910==    by 0x8122D8C: normal_cmd (normal.c:1200)
==11910==    by 0x80E5FD5: main_loop (main.c:1180)
==11910==    by 0x80E5B22: main (main.c:939)
==11910==
==11910== Conditional jump or move depends on uninitialised value(s)
==11910==    at 0x81BC35D: win_valid (window.c:1234)
==11910==    by 0x80CC2B5: aucmd_restbuf (fileio.c:8409)
==11910==    by 0x80626D9: ex_diffgetput (diff.c:2348)
==11910==    by 0x80A679B: do_one_cmd (ex_docmd.c:2622)
==11910==    by 0x80A401B: do_cmdline (ex_docmd.c:1096)
==11910==    by 0x8129708: nv_colon (normal.c:5233)
==11910==    by 0x8122D8C: normal_cmd (normal.c:1200)
==11910==    by 0x80E5FD5: main_loop (main.c:1180)
==11910==    by 0x80E5B22: main (main.c:939)
==11910==
==11910== Conditional jump or move depends on uninitialised value(s)
==11910==    at 0x81BC378: win_valid (window.c:1237)
==11910==    by 0x80CC2B5: aucmd_restbuf (fileio.c:8409)
==11910==    by 0x80626D9: ex_diffgetput (diff.c:2348)
==11910==    by 0x80A679B: do_one_cmd (ex_docmd.c:2622)
==11910==    by 0x80A401B: do_cmdline (ex_docmd.c:1096)
==11910==    by 0x8129708: nv_colon (normal.c:5233)
==11910==    by 0x8122D8C: normal_cmd (normal.c:1200)
==11910==    by 0x80E5FD5: main_loop (main.c:1180)
==11910==    by 0x80E5B22: main (main.c:939)

Attached patch (against vim-7.2.84) fixes it by making sure
that :diffget or :diffput don't do anything when the argument
specifies the same buffer as the current buffer.  Maybe an
error message could also be given but I don't think it's
necessary.

-- Dominique

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

Index: diff.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/diff.c,v
retrieving revision 1.32
diff -c -r1.32 diff.c
*** diff.c	30 Nov 2008 14:16:37 -0000	1.32
--- diff.c	13 Jan 2009 19:11:56 -0000
***************
*** 8,14 ****
   */
  
  /*
!  * diff.c: code for diff'ing two or three buffers.
   */
  
  #include "vim.h"
--- 8,14 ----
   */
  
  /*
!  * diff.c: code for diff'ing two, three or four buffers.
   */
  
  #include "vim.h"
***************
*** 116,122 ****
   * Add a buffer to make diffs for.
   * Call this when a new buffer is being edited in the current window where
   * 'diff' is set.
!  * Marks the current buffer as being part of the diff and requireing updating.
   * This must be done before any autocmd, because a command may use info
   * about the screen contents.
   */
--- 116,122 ----
   * Add a buffer to make diffs for.
   * Call this when a new buffer is being edited in the current window where
   * 'diff' is set.
!  * Marks the current buffer as being part of the diff and requiring updating.
   * This must be done before any autocmd, because a command may use info
   * about the screen contents.
   */
***************
*** 929,935 ****
  	goto theend;
  
  #ifdef UNIX
!     /* Temporaraly chdir to /tmp, to avoid patching files in the current
       * directory when the patch file contains more than one patch.  When we
       * have our own temp dir use that instead, it will be cleaned up when we
       * exit (any .rej files created).  Don't change directory if we can't
--- 929,935 ----
  	goto theend;
  
  #ifdef UNIX
!     /* Temporarily chdir to /tmp, to avoid patching files in the current
       * directory when the patch file contains more than one patch.  When we
       * have our own temp dir use that instead, it will be cleaned up when we
       * exit (any .rej files created).  Don't change directory if we can't
***************
*** 2129,2134 ****
--- 2129,2136 ----
  	    EMSG2(_("E102: Can't find buffer \"%s\""), eap->arg);
  	    return;
  	}
+ 	if (buf == curbuf)
+ 	    return;		/* nothing to do */
  	idx_other = diff_buf_idx(buf);
  	if (idx_other == DB_COUNT)
  	{

Raspunde prin e-mail lui