Hi
Valgrind memory checker finds the following bug in cscope
feature of vim. I am using vim-7.1 (patches 1-82) on Linux x86.
==8606== Invalid write of size 1
==8606== at 0x80D17C0: cs_fgets (if_cscope.c:267)
==8606== by 0x818F1E6: find_tags (tag.c:1670)
==8606== by 0x818D0F4: do_tag (tag.c:548)
==8606== by 0x80D2E88: cs_find_common (if_cscope.c:1163)
==8606== by 0x80D28FF: cs_find (if_cscope.c:975)
==8606== by 0x80D14A2: do_cscope_general (if_cscope.c:135)
==8606== by 0x80D14D1: do_cscope (if_cscope.c:150)
==8606== by 0x809A1FB: do_one_cmd (ex_docmd.c:2622)
==8606== by 0x8097B18: do_cmdline (ex_docmd.c:1100)
==8606== by 0x8114018: nv_colon (normal.c:5168)
==8606== by 0x810E16F: normal_cmd (normal.c:1141)
==8606== by 0x80D59F5: main_loop (main.c:1180)
==8606== by 0x80D5609: main (main.c:939)
==8606== Address 0x7D81D50 is 0 bytes after a block of size 512 alloc'd
==8606== at 0x4021620: malloc (vg_replace_malloc.c:149)
==8606== by 0x8100354: lalloc (misc2.c:857)
==8606== by 0x810027E: alloc (misc2.c:756)
==8606== by 0x818E9B5: find_tags (tag.c:1393)
==8606== by 0x818D0F4: do_tag (tag.c:548)
==8606== by 0x80D2E88: cs_find_common (if_cscope.c:1163)
==8606== by 0x80D28FF: cs_find (if_cscope.c:975)
==8606== by 0x80D14A2: do_cscope_general (if_cscope.c:135)
==8606== by 0x80D14D1: do_cscope (if_cscope.c:150)
==8606== by 0x809A1FB: do_one_cmd (ex_docmd.c:2622)
==8606== by 0x8097B18: do_cmdline (ex_docmd.c:1100)
==8606== by 0x8114018: nv_colon (normal.c:5168)
==8606== by 0x810E16F: normal_cmd (normal.c:1141)
==8606== by 0x80D59F5: main_loop (main.c:1180)
==8606== by 0x80D5609: main (main.c:939)
I can reproduce the bug by creating a cscope database
of vim source tree, then by performing the following search
in vim: ":cs find e e".
The code in if_cscope.c is:
254 int
255 cs_fgets(buf, size)
256 char_u *buf;
257 int size;
258 {
259 char *p;
260
261 if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
262 return TRUE;
263
264 if ((int)strlen(p) > size)
265 {
266 strncpy((char *)buf, p, size - 1);
267 buf[size] = '\0';
268 }
269 else
270 (void)strcpy((char *)buf, p);
271
272 return FALSE;
273 } /* cs_fgets */
cs_fgets() is called from tag.c:1670 with size parameter
equal to LSIZE (512). Line 267 thus writes '\0' in buf[512].
But buf buffer was allocated with 512 bytes (LSIZE) so
line 267 writes 1 byte beyond allocated size.
Following patch fixes it and also simplifies code:
diff -c -r1.22 if_cscope.c
*** if_cscope.c 11 Mar 2007 14:48:29 -0000 1.22
--- if_cscope.c 19 Aug 2007 19:07:34 -0000
***************
*** 261,274 ****
if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
return TRUE;
! if ((int)strlen(p) > size)
! {
! strncpy((char *)buf, p, size - 1);
! buf[size] = '\0';
! }
! else
! (void)strcpy((char *)buf, p);
!
return FALSE;
} /* cs_fgets */
--- 261,267 ----
if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
return TRUE;
! vim_strncpy(buf, (char_u *)p, size - 1);
return FALSE;
} /* cs_fgets */
-- Dominique
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---