Hi

I can reproduce the following error using Valgrind with Vim-7.2.245 (huge):

==29234== Invalid read of size 1
==29234==    at 0x80D9F6F: check_map_keycodes (getchar.c:4931)
==29234==    by 0x81B1258: set_termname (term.c:2030)
==29234==    by 0x81B19B0: termcapinit (term.c:2510)
==29234==    by 0x81C5C8E: gui_start (gui.c:91)
==29234==    by 0x81CB7F4: ex_gui (gui.c:4753)
==29234==    by 0x80A6C50: do_one_cmd (ex_docmd.c:2629)
==29234==    by 0x80A4487: do_cmdline (ex_docmd.c:1098)
==29234==    by 0x80A3B20: do_cmdline_cmd (ex_docmd.c:704)
==29234==    by 0x80E93B5: exe_commands (main.c:2697)
==29234==    by 0x80E6DA7: main (main.c:874)
==29234==  Address 0x5de7f6a is 0 bytes after a block of size 10 alloc'd
==29234==    at 0x402603E: malloc (vg_replace_malloc.c:207)
==29234==    by 0x8114BF6: lalloc (misc2.c:866)
==29234==    by 0x8114B01: alloc (misc2.c:765)
==29234==    by 0x811500F: vim_strsave (misc2.c:1177)
==29234==    by 0x80D7F30: do_map (getchar.c:3597)
==29234==    by 0x80AF0D3: do_exmap (ex_docmd.c:8062)
==29234==    by 0x80AA57F: ex_map (ex_docmd.c:4809)
==29234==    by 0x80A6C50: do_one_cmd (ex_docmd.c:2629)
==29234==    by 0x80A4487: do_cmdline (ex_docmd.c:1098)
==29234==    by 0x80A2731: do_source (ex_cmds2.c:3116)
==29234==    by 0x80A1BE7: source_callback (ex_cmds2.c:2555)
==29234==    by 0x80A1DC4: do_in_runtimepath (ex_cmds2.c:2649)
==29234==    by 0x80A1C11: source_runtime (ex_cmds2.c:2569)
==29234==    by 0x80E697B: main (main.c:569)
(and more errors follow after that)

Steps to reproduce:

  1/ create an empty file: ~/.vimrc
  2/ run: valgrind vim -F -c ':gui -f' 2> valgrind.log
  3/ observe error in valgrind.log when the GUI pops up.

I can see why it happens, but I'm not sure how it should be fixed.

Code in getchar.c is:

  4927     if (i == 0)
  4928         p = mp->m_keys;     /* once for the "from" part */
  4929     else
  4930         p = mp->m_str;      /* and once for the "to" part */
!!4931     while (*p)
  4932     {
  4933         if (*p == K_SPECIAL)
  4934         {
  4935             ++p;
  4936             if (*p < 128)   /* for "normal" tcap entries */
  4937             {
!!4938                 buf[0] = p[0];
!!4939                 buf[1] = p[1];
  4940                 buf[2] = NUL;
  4941                 (void)add_termcap_entry(buf, FALSE);
  4942             }
  4943             ++p;
  4944         }
  4945         ++p;
  4946     }

When read overflow happens at line 4931, I see that:
- i is ........... 1
- mp->m_str is ... "'bk<80>b"
- p is ........... "<80>b"

... where <80> is the single character K_SPECIAL.  Comment in keymap.h
at line 22 says that the K_SPECIAL should always be followed by 2 bytes (and
code at getchar.c:4938 assumes that), but this is not the case here since there
is only 1 character after K_SPECIAL, hence read overflow.

Bug happens because mp->m_str string was swapped left to right as follows
in getchar.c:

  3253     if (hasarg)
  3254     {
  3255         if (STRICMP(rhs, "<nop>") == 0)     /* "<Nop>" means nothing */
  3256             rhs = (char_u *)"";
  3257         else
!!3258             rhs = replace_termcodes(rhs, &arg_buf, FALSE, TRUE, special);
  3259     }
  3260
  3261 #ifdef FEAT_FKMAP
  3262     /*
  3263      * when in right-to-left mode and alternate keymap option set,
  3264      * reverse the character flow in the rhs in Farsi.
  3265      */
  3266     if (p_altkeymap && curwin->w_p_rl)
!!3267         lrswap(rhs);
  3268 #endif
  ....
  3597   mp->m_str = vim_strsave(rhs);

rhs is initially set to "b<80>kb'" at line 3258 (where <80> is the single
character K_SPECIAL).  Then call to lrswap(rhs) at line 3267 swaps from left
to right and rhs becomes: "'bk<80>b".  Notice that reversing the string reverses
the sequence after K_SPECIAL, and there is as a result only one single
character after K_SPECIAL (hence bug later).

I'm not familiar enough with the code to tell whether:
- lrswap() should be changed to avoid swapping character sequence
  after K_SPECIAL
- or whether code that uses K_SPECIAL at line getchar.c:4931 should be changed
  take into account that K_SPECIAL sequence may have been swapped.
- or maybe the string should not have been swapped?

-- Dominique

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

Raspunde prin e-mail lui