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
-~----------~----~----~----~------~----~------~--~---