Hi

Valgrind memory checker detects a bug when entering the command ":cs find g".
(requires support for cscope in vim)

==19660== Conditional jump or move depends on uninitialised value(s)
==19660==    at 0x80D27F4: cs_find (if_cscope.c:969)
==19660==    by 0x80D13E6: do_cscope_general (if_cscope.c:135)
==19660==    by 0x80D1415: do_cscope (if_cscope.c:150)
==19660==    by 0x809A1FB: do_one_cmd (ex_docmd.c:2622)
==19660==    by 0x8097B18: do_cmdline (ex_docmd.c:1100)
==19660==    by 0x8113F5C: nv_colon (normal.c:5168)
==19660==    by 0x810E0B3: normal_cmd (normal.c:1141)
==19660==    by 0x80D5939: main_loop (main.c:1180)
==19660==    by 0x80D554D: main (main.c:939)

Relevant code in if_cscope.c is:

   951 cs_find(eap)
   952     exarg_T *eap;
   953 {
   954     char *opt, *pat;
   955
   956     if (cs_check_for_connections() == FALSE)
   957     {
   958         (void)EMSG(_("E567: no cscope connections"));
   959         return FALSE;
   960     }
   961
   962     if ((opt = strtok((char *)NULL, (const char *)" ")) == NULL)
   963     {
   964         cs_usage_msg(Find);
   965         return FALSE;
   966     }
   967
   968     pat = opt + strlen(opt) + 1;
!! 969     if (pat == NULL || (pat != NULL && pat[0] == '\0'))
   970     {
   971         cs_usage_msg(Find);
   972         return FALSE;
   973     }
   974
   975     return cs_find_common(opt, pat, eap->forceit, TRUE,
   976                           eap->cmdidx == CMD_lcscope);
   977 } /* cs_find */

Vim accesses uninitialized memory after the string ":cs find g"
at line 969.  As a result, it may display usage or may call
(incorrectly) cs_find_common().

Bug happens because command ":cs find g" is illegal (pattern
to search is missing).  Correct command would be something like
":cs find some_pattern". However, entering an incorrect command
should not cause vim to to access uninitialized memory.  It
should display the usage of command.

I attach a patch which fixes it. It calls strtok() another time
to find the pattern after "cs find g".  Note that patch changes
the behavior slightly when entering several spaces before pattern.
With patch, ":cs find   pattern" will search for "pattern".
Without patch, ":cs find   pattern" will search for "  pattern".
I'm not sure whether that's a better behavior or not.  I personally
prefer behavior after patch.  At least it fixes the access to
uninitialized memory. If original behavior must be preserved,
then bug needs to be fixed differently.

I was using vim-7.1 (patches 1-79) built with +cscope feature
on Linux x86.

-- Dominique

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

Index: if_cscope.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/if_cscope.c,v
retrieving revision 1.22
diff -c -r1.22 if_cscope.c
*** if_cscope.c 11 Mar 2007 14:48:29 -0000      1.22
--- if_cscope.c 18 Aug 2007 16:08:22 -0000
***************
*** 952,957 ****
--- 952,958 ----
      exarg_T *eap;
  {
      char *opt, *pat;
+     int jump;
  
      if (cs_check_for_connections() == FALSE)
      {
***************
*** 964,979 ****
        cs_usage_msg(Find);
        return FALSE;
      }
  
!     pat = opt + strlen(opt) + 1;
!     if (pat == NULL || (pat != NULL && pat[0] == '\0'))
      {
        cs_usage_msg(Find);
        return FALSE;
      }
  
!     return cs_find_common(opt, pat, eap->forceit, TRUE,
!                         eap->cmdidx == CMD_lcscope);
  } /* cs_find */
  
  
--- 965,982 ----
        cs_usage_msg(Find);
        return FALSE;
      }
+     opt = strdup(opt);
  
!     if ((pat = strtok((char *)NULL, (const char *)" ")) == NULL)
      {
        cs_usage_msg(Find);
        return FALSE;
      }
  
!     jump = cs_find_common(opt, pat, eap->forceit, TRUE,
!                         eap->cmdidx == CMD_lcscope);
!     vim_free(opt);
!     return jump;
  } /* cs_find */
  
  

Raspunde prin e-mail lui