Hi

I can reproduce the following error with Vim-7.2.148 using
Valgrind memory checker.  The steps to reproduce the error
are too complicated to detail here. I have not found a
simple test case but I can reproduce the problem 100% of
the time.

==15886== Invalid read of size 1
==15886==    at 0x81796E9: find_pattern_in_path (search.c:5117)
==15886==    by 0x8069229: ins_compl_get_exp (edit.c:4015)
==15886==    by 0x8069F0A: ins_compl_next (edit.c:4434)
==15886==    by 0x806B19C: ins_complete (edit.c:5066)
==15886==    by 0x8064FDA: edit (edit.c:1343)
==15886==    by 0x812F640: invoke_edit (normal.c:8888)
==15886==    by 0x812F5E6: nv_edit (normal.c:8861)
==15886==    by 0x8122E06: normal_cmd (normal.c:1189)
==15886==    by 0x80E62C1: main_loop (main.c:1180)
==15886==    by 0x80E5E0E: main (main.c:939)
==15886==  Address 0x61d1ad8 is 0 bytes after a block of size 4,096 alloc'd
==15886==    at 0x402603E: malloc (vg_replace_malloc.c:207)
==15886==    by 0x811366E: lalloc (misc2.c:866)
==15886==    by 0x811358A: alloc (misc2.c:765)
==15886==    by 0x80F351C: mf_alloc_bhdr (memfile.c:973)
==15886==    by 0x80F2B3C: mf_new (memfile.c:395)
==15886==    by 0x80F897D: ml_new_data (memline.c:3164)
==15886==    by 0x80F3FBB: ml_open (memline.c:373)
==15886==    by 0x8052C60: open_buffer (buffer.c:85)
==15886==    by 0x8097AD3: do_ecmd (ex_cmds.c:3655)
==15886==    by 0x80ADE5F: do_exedit (ex_docmd.c:7569)
==15886==    by 0x80ADAB7: ex_open (ex_docmd.c:7454)
==15886==    by 0x80A6527: do_one_cmd (ex_docmd.c:2622)
==15886==    by 0x80A3DA7: do_cmdline (ex_docmd.c:1096)
==15886==    by 0x80A32BA: do_exmode (ex_docmd.c:653)
==15886==    by 0x81296C8: nv_exmode (normal.c:5176)
==15886==    by 0x8122E06: normal_cmd (normal.c:1189)
==15886==    by 0x80E62C1: main_loop (main.c:1180)
==15886==    by 0x80E5E0E: main (main.c:939)

The code in search.c is as follows:

5117         if (def_regmatch.regprog == NULL
5118 #ifdef FEAT_INS_EXPAND
5119                 && action == ACTION_EXPAND
5120                 && !(compl_cont_status & CONT_SOL)
5121 #endif
5122                 && *(p = startp + 1))
5123             goto search_line;

Adding some debug printf, I see that bug happens when
dereferencing 'startp + 1'.  Pointer startp is already at
the end of the string, *startp is NUL, and *(startp + 1)
is thus 1 byte beyond the end of the string, causing
invalid memory access.

Before error is detected, startp was initialized at
line 4870:

4866        else if (regmatch.regprog != NULL
4867                 && vim_regexec(&regmatch, line, (colnr_T)(p - line)))
4868        {
4869            matched = TRUE;
4870            startp = regmatch.startp[0];

Putting a printf() there, I could see that line had an empty
length [strlen(line) is 0] and 'p - line' is 0.  *startp is NUL.

Attached patch fixes it (plus some typos).  However,
function find_pattern_in_path() in quite complicated so
please review the fix.

-- Dominique

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

Index: search.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/search.c,v
retrieving revision 1.68
diff -c -r1.68 search.c
*** search.c	18 Jul 2008 10:05:58 -0000	1.68
--- search.c	8 Apr 2009 19:45:49 -0000
***************
*** 2327,2333 ****
  		    for (col = pos.col; check_prevcol(linep, col, '\\', &col);)
  			bslcnt++;
  		}
! 		/* Only accept a match when 'M' is in 'cpo' or when ecaping is
  		 * what we expect. */
  		if (cpo_bsl || (bslcnt & 1) == match_escaped)
  		{
--- 2327,2333 ----
  		    for (col = pos.col; check_prevcol(linep, col, '\\', &col);)
  			bslcnt++;
  		}
! 		/* Only accept a match when 'M' is in 'cpo' or when escaping is
  		 * what we expect. */
  		if (cpo_bsl || (bslcnt & 1) == match_escaped)
  		{
***************
*** 4663,4669 ****
  			    msg_putchar('\n');	    /* cursor below last one */
  			    if (!got_int)	    /* don't display if 'q'
  						       typed at "--more--"
! 						       mesage */
  			    {
  				msg_home_replace_hl(new_fname);
  				MSG_PUTS(_(" (includes previously listed match)"));
--- 4663,4669 ----
  			    msg_putchar('\n');	    /* cursor below last one */
  			    if (!got_int)	    /* don't display if 'q'
  						       typed at "--more--"
! 						       message */
  			    {
  				msg_home_replace_hl(new_fname);
  				MSG_PUTS(_(" (includes previously listed match)"));
***************
*** 4975,4981 ****
  					    || IObuff[i-2] == '!'))))
  				IObuff[i++] = ' ';
  			}
! 			/* copy as much as posible of the new word */
  			if (p - aux >= IOSIZE - i)
  			    p = aux + IOSIZE - i - 1;
  			STRNCPY(IObuff + i, aux, p - aux);
--- 4975,4981 ----
  					    || IObuff[i-2] == '!'))))
  				IObuff[i++] = ' ';
  			}
! 			/* copy as much as possible of the new word */
  			if (p - aux >= IOSIZE - i)
  			    p = aux + IOSIZE - i - 1;
  			STRNCPY(IObuff + i, aux, p - aux);
***************
*** 5010,5016 ****
  		    if (did_show)
  			msg_putchar('\n');	/* cursor below last one */
  		    if (!got_int)		/* don't display if 'q' typed
! 						    at "--more--" mesage */
  			msg_home_replace_hl(curr_fname);
  		    prev_fname = curr_fname;
  		}
--- 5010,5016 ----
  		    if (did_show)
  			msg_putchar('\n');	/* cursor below last one */
  		    if (!got_int)		/* don't display if 'q' typed
! 						    at "--more--" message */
  			msg_home_replace_hl(curr_fname);
  		    prev_fname = curr_fname;
  		}
***************
*** 5119,5124 ****
--- 5119,5125 ----
  		    && action == ACTION_EXPAND
  		    && !(compl_cont_status & CONT_SOL)
  #endif
+ 		    && *startp
  		    && *(p = startp + 1))
  		goto search_line;
  	}

Raspunde prin e-mail lui