Loading ...
Sorry, an error occurred while loading the content.

bug with K_SPECIAL and Farsi

Expand Messages
  • Dominique PellĂ©
    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
    Message 1 of 1 , Aug 2, 2009
    • 0 Attachment
      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
      -~----------~----~----~----~------~----~------~--~---
    Your message has been successfully submitted and would be delivered to recipients shortly.