jeromejj / vim

Automatically exported from code.google.com/p/vim
0 stars 0 forks source link

valgrind error "Invalid read of size 1" in find_var_in_ht (eval.c:20062) in test91 #128

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Valgrind memory checker reports the following error when
running "make test" in test91:

==17704== Invalid read of size 1
==17704==    at 0x4511AA: find_var_in_ht (eval.c:20062)
==17704==    by 0x444D61: f_gettabvar (eval.c:11782)
==17704==    by 0x43FD17: call_func (eval.c:8531)
==17704==    by 0x43F7E9: get_func_tv (eval.c:8344)
==17704==    by 0x43B213: eval7 (eval.c:5164)
==17704==    by 0x43AA8D: eval6 (eval.c:4816)
==17704==    by 0x43A652: eval5 (eval.c:4632)
==17704==    by 0x439BE3: eval4 (eval.c:4325)
==17704==    by 0x439A3F: eval3 (eval.c:4237)
==17704==    by 0x4398BE: eval2 (eval.c:4166)
==17704==    by 0x4396FD: eval1 (eval.c:4091)
==17704==    by 0x43F74E: get_func_tv (eval.c:8329)
==17704==    by 0x43B213: eval7 (eval.c:5164)
==17704==    by 0x43AA8D: eval6 (eval.c:4816)
==17704==    by 0x43A652: eval5 (eval.c:4632)
==17704==    by 0x439BE3: eval4 (eval.c:4325)
==17704==    by 0x439A3F: eval3 (eval.c:4237)
==17704==    by 0x4398BE: eval2 (eval.c:4166)
==17704==    by 0x4396FD: eval1 (eval.c:4091)
==17704==    by 0x43965C: eval0 (eval.c:4048)
==17704==    by 0x434858: eval_to_string (eval.c:1361)
==17704==    by 0x501F52: get_expr_line (ops.c:818)
==17704==    by 0x502F52: get_spec_reg (ops.c:1504)
==17704==    by 0x506CEB: do_put (ops.c:3362)
==17704==    by 0x479AD3: ex_put (ex_docmd.c:8570)
==17704==    by 0x46FE4C: do_one_cmd (ex_docmd.c:2684)
==17704==    by 0x46D4A8: do_cmdline (ex_docmd.c:1122)
==17704==    by 0x4F9B6A: nv_colon (normal.c:5453)
==17704==    by 0x4F2740: normal_cmd (normal.c:1199)
==17704==    by 0x5D088A: main_loop (main.c:1322)
==17704==    by 0x5D01E7: main (main.c:1013)
==17704==  Address 0xca9d97e is 2 bytes before a block of size 1 alloc'd
==17704==    at 0x4C2C78F: malloc (vg_replace_malloc.c:270)
==17704==    by 0x4DFE4C: lalloc (misc2.c:929)
==17704==    by 0x4DFD5A: alloc (misc2.c:828)
==17704==    by 0x43C3AE: get_lit_string_tv (eval.c:5783)
==17704==    by 0x43AFBE: eval7 (eval.c:5083)
==17704==    by 0x43AA8D: eval6 (eval.c:4816)
==17704==    by 0x43A652: eval5 (eval.c:4632)
==17704==    by 0x439BE3: eval4 (eval.c:4325)
==17704==    by 0x439A3F: eval3 (eval.c:4237)
==17704==    by 0x4398BE: eval2 (eval.c:4166)
==17704==    by 0x4396FD: eval1 (eval.c:4091)
==17704==    by 0x43F74E: get_func_tv (eval.c:8329)
==17704==    by 0x43B213: eval7 (eval.c:5164)
==17704==    by 0x43AA8D: eval6 (eval.c:4816)
==17704==    by 0x43A652: eval5 (eval.c:4632)
==17704==    by 0x439BE3: eval4 (eval.c:4325)
==17704==    by 0x439A3F: eval3 (eval.c:4237)
==17704==    by 0x4398BE: eval2 (eval.c:4166)
==17704==    by 0x4396FD: eval1 (eval.c:4091)
==17704==    by 0x43F74E: get_func_tv (eval.c:8329)
==17704==    by 0x43B213: eval7 (eval.c:5164)
==17704==    by 0x43AA8D: eval6 (eval.c:4816)
==17704==    by 0x43A652: eval5 (eval.c:4632)
==17704==    by 0x439BE3: eval4 (eval.c:4325)
==17704==    by 0x439A3F: eval3 (eval.c:4237)
==17704==    by 0x4398BE: eval2 (eval.c:4166)
==17704==    by 0x4396FD: eval1 (eval.c:4091)
==17704==    by 0x43965C: eval0 (eval.c:4048)
==17704==    by 0x434858: eval_to_string (eval.c:1361)
==17704==    by 0x501F52: get_expr_line (ops.c:818)
==17704==    by 0x502F52: get_spec_reg (ops.c:1504)
==17704==    by 0x506CEB: do_put (ops.c:3362)
==17704==    by 0x479AD3: ex_put (ex_docmd.c:8570)
==17704==    by 0x46FE4C: do_one_cmd (ex_docmd.c:2684)
==17704==    by 0x46D4A8: do_cmdline (ex_docmd.c:1122)
==17704==    by 0x4F9B6A: nv_colon (normal.c:5453)
==17704==    by 0x4F2740: normal_cmd (normal.c:1199)
==17704==    by 0x5D088A: main_loop (main.c:1322)
==17704==    by 0x5D01E7: main (main.c:1013)

Code in eval.c around line 20062 looks like this:

  20051     static dictitem_T *
  20052 find_var_in_ht(ht, varname, writing)
  20053     hashtab_T   *ht;
  20054     char_u      *varname;
  20055     int         writing;
  20056 {
  20057     hashitem_T  *hi;
  20058 
  20059     if (*varname == NUL)
  20060     {
  20061         /* Must be something like "s:", otherwise "ht" would be NULL. */
!!20062         switch (varname[-2])
  20063         {
  20064             case 's': return &SCRIPT_SV(current_SID)->sv_var;
  20065             case 'g': return &globvars_var;
  20066             case 'v': return &vimvars_var;
  20067             case 'b': return &curbuf->b_bufvar;
  20068             case 'w': return &curwin->w_winvar;

It looks quite dangerous to take varname[-2] assuming that
there is valid memory before varname.  The comment at above
line 20061 says that it should be valid, but it's proven
wrong with Valgrind: Valgrind indicates that varname was
allocated in  get_lit_string_tv (eval.c:5783):

  5780     /*
  5781      * Copy the string into allocated memory, handling '' to ' reduction.
  5782      */
!!5783     str = alloc((unsigned)((p - *arg) - reduce));

test91 is fairly recent as it was added in this checkin:

$ hg -v log -r4157:cb185366f5c8
changeset:   4157:cb185366f5c8
tag:         v7-3-831
user:        Bram Moolenaar <bram@vim.org>
date:        Wed Feb 20 21:12:10 2013 +0100
files:       runtime/doc/eval.txt src/eval.c src/testdir/Make_amiga.mak 
src/testdir/Make_dos.mak src/testdir/Make_ming.mak src/testdir/Make_os2.mak 
src/testdir/Make_vms.mms src/testdir/Makefile src/testdir/test91.in 
src/testdir/test91.ok src/version.c
description:
updated for version 7.3.831
Problem:    Clumsy to handle the situation that a variable does not exist.
Solution:   Add default value to getbufvar() et al. (Shougo Matsushita,
        Hirohito Higashi)

What steps will reproduce the problem?

1. Uncomment VALGRIND = ... in src/testdir/Makefile
2. cd src/testdir
3. make test91.out
4. observe valgrind errors in valgrind.test91

What is the expected output? What do you see instead?

Valgrind should obviously not complain with "Invalid read" errors.

What version of the product are you using? On what operating system?

Vim-7.3.888, huge, on Linux x86_64.

Original issue reported on code.google.com by dominiqu...@gmail.com on 12 Apr 2013 at 10:50

GoogleCodeExporter commented 9 years ago
Patch 7.3.895 should fix this.

Original comment by brammool...@gmail.com on 15 Apr 2013 at 11:19