Patch 7.3.431
Problem:    Fetching a key at a prompt may be confused by escape sequences.
            Especially when getting a prompt at a VimEnter autocommand.
            (Alex Efros)
Solution:   Properly handle escape sequences deleted by check_termcode().
Files:      src/getchar.c, src/misc1.c, src/term.c, src/proto/term.pro


*** ../vim-7.3.430/src/getchar.c        2012-02-05 01:18:41.000000000 +0100
--- src/getchar.c       2012-02-05 22:04:33.000000000 +0100
***************
*** 2282,2288 ****
                                                   typebuf.tb_off] == RM_YES))
                                && !timedout)
                        {
!                           keylen = check_termcode(max_mlen + 1, NULL, 0);
  
                            /* If no termcode matched but 'pastetoggle'
                             * matched partially it's like an incomplete key
--- 2282,2289 ----
                                                   typebuf.tb_off] == RM_YES))
                                && !timedout)
                        {
!                           keylen = check_termcode(max_mlen + 1,
!                                                              NULL, 0, NULL);
  
                            /* If no termcode matched but 'pastetoggle'
                             * matched partially it's like an incomplete key
*** ../vim-7.3.430/src/misc1.c  2012-01-10 18:37:53.000000000 +0100
--- src/misc1.c 2012-02-05 21:59:53.000000000 +0100
***************
*** 3105,3112 ****
      int
  get_keystroke()
  {
! #define CBUFLEN 151
!     char_u    buf[CBUFLEN];
      int               len = 0;
      int               n;
      int               save_mapped_ctrl_c = mapped_ctrl_c;
--- 3105,3113 ----
      int
  get_keystroke()
  {
!     char_u    *buf = NULL;
!     int               buflen = 150;
!     int               maxlen;
      int               len = 0;
      int               n;
      int               save_mapped_ctrl_c = mapped_ctrl_c;
***************
*** 3118,3129 ****
        cursor_on();
        out_flush();
  
        /* First time: blocking wait.  Second time: wait up to 100ms for a
!        * terminal code to complete.  Leave some room for check_termcode() to
!        * insert a key code into (max 5 chars plus NUL).  And
!        * fix_input_buffer() can triple the number of bytes. */
!       n = ui_inchar(buf + len, (CBUFLEN - 6 - len) / 3,
!                                                   len == 0 ? -1L : 100L, 0);
        if (n > 0)
        {
            /* Replace zero and CSI by a special key code. */
--- 3119,3147 ----
        cursor_on();
        out_flush();
  
+       /* Leave some room for check_termcode() to insert a key code into (max
+        * 5 chars plus NUL).  And fix_input_buffer() can triple the number of
+        * bytes. */
+       maxlen = (buflen - 6 - len) / 3;
+       if (buf == NULL)
+           buf = alloc(buflen);
+       else if (maxlen < 10)
+       {
+           /* Need some more space. This migth happen when receiving a long
+            * escape sequence. */
+           buflen += 100;
+           buf = vim_realloc(buf, buflen);
+           maxlen = (buflen - 6 - len) / 3;
+       }
+       if (buf == NULL)
+       {
+           do_outofmem_msg((long_u)buflen);
+           return ESC;  /* panic! */
+       }
+ 
        /* First time: blocking wait.  Second time: wait up to 100ms for a
!        * terminal code to complete. */
!       n = ui_inchar(buf + len, maxlen, len == 0 ? -1L : 100L, 0);
        if (n > 0)
        {
            /* Replace zero and CSI by a special key code. */
***************
*** 3135,3141 ****
            ++waited;       /* keep track of the waiting time */
  
        /* Incomplete termcode and not timed out yet: get more characters */
!       if ((n = check_termcode(1, buf, len)) < 0
               && (!p_ttimeout || waited * 100L < (p_ttm < 0 ? p_tm : p_ttm)))
            continue;
  
--- 3153,3159 ----
            ++waited;       /* keep track of the waiting time */
  
        /* Incomplete termcode and not timed out yet: get more characters */
!       if ((n = check_termcode(1, buf, buflen, &len)) < 0
               && (!p_ttimeout || waited * 100L < (p_ttm < 0 ? p_tm : p_ttm)))
            continue;
  
***************
*** 3203,3209 ****
        {
            if (MB_BYTE2LEN(n) > len)
                continue;       /* more bytes to get */
!           buf[len >= CBUFLEN ? CBUFLEN - 1 : len] = NUL;
            n = (*mb_ptr2char)(buf);
        }
  #endif
--- 3221,3227 ----
        {
            if (MB_BYTE2LEN(n) > len)
                continue;       /* more bytes to get */
!           buf[len >= buflen ? buflen - 1 : len] = NUL;
            n = (*mb_ptr2char)(buf);
        }
  #endif
***************
*** 3213,3218 ****
--- 3231,3237 ----
  #endif
        break;
      }
+     vim_free(buf);
  
      mapped_ctrl_c = save_mapped_ctrl_c;
      return n;
*** ../vim-7.3.430/src/term.c   2012-01-26 13:01:54.000000000 +0100
--- src/term.c  2012-02-05 21:45:09.000000000 +0100
***************
*** 3785,3798 ****
   * With a match, the match is removed, the replacement code is inserted in
   * typebuf.tb_buf[] and the number of characters in typebuf.tb_buf[] is
   * returned.
!  * When "buf" is not NULL, it is used instead of typebuf.tb_buf[]. "buflen" is
!  * then the length of the string in buf[].
   */
      int
! check_termcode(max_offset, buf, buflen)
      int               max_offset;
      char_u    *buf;
!     int               buflen;
  {
      char_u    *tp;
      char_u    *p;
--- 3785,3800 ----
   * With a match, the match is removed, the replacement code is inserted in
   * typebuf.tb_buf[] and the number of characters in typebuf.tb_buf[] is
   * returned.
!  * When "buf" is not NULL, buf[bufsize] is used instead of typebuf.tb_buf[].
!  * "buflen" is then the length of the string in buf[] and is updated for
!  * inserts and deletes.
   */
      int
! check_termcode(max_offset, buf, bufsize, buflen)
      int               max_offset;
      char_u    *buf;
!     int               bufsize;
!     int               *buflen;
  {
      char_u    *tp;
      char_u    *p;
***************
*** 3864,3873 ****
        }
        else
        {
!           if (offset >= buflen)
                break;
            tp = buf + offset;
!           len = buflen - offset;
        }
  
        /*
--- 3866,3875 ----
        }
        else
        {
!           if (offset >= *buflen)
                break;
            tp = buf + offset;
!           len = *buflen - offset;
        }
  
        /*
***************
*** 5002,5013 ****
            if (extra < 0)
                /* remove matched characters */
                mch_memmove(buf + offset, buf + offset - extra,
!                                          (size_t)(buflen + offset + extra));
            else if (extra > 0)
!               /* insert the extra space we need */
                mch_memmove(buf + offset + extra, buf + offset,
!                                                  (size_t)(buflen - offset));
            mch_memmove(buf + offset, string, (size_t)new_slen);
        }
        return retval == 0 ? (len + extra + offset) : retval;
      }
--- 5004,5021 ----
            if (extra < 0)
                /* remove matched characters */
                mch_memmove(buf + offset, buf + offset - extra,
!                                          (size_t)(*buflen + offset + extra));
            else if (extra > 0)
!           {
!               /* Insert the extra space we need.  If there is insufficient
!                * space return -1. */
!               if (*buflen + extra + new_slen >= bufsize)
!                   return -1;
                mch_memmove(buf + offset + extra, buf + offset,
!                                                  (size_t)(*buflen - offset));
!           }
            mch_memmove(buf + offset, string, (size_t)new_slen);
+           *buflen = *buflen + extra + new_slen;
        }
        return retval == 0 ? (len + extra + offset) : retval;
      }
*** ../vim-7.3.430/src/proto/term.pro   2010-08-15 21:57:28.000000000 +0200
--- src/proto/term.pro  2012-02-05 21:45:16.000000000 +0100
***************
*** 50,56 ****
  char_u *get_termcode __ARGS((int i));
  void del_termcode __ARGS((char_u *name));
  void set_mouse_topline __ARGS((win_T *wp));
! int check_termcode __ARGS((int max_offset, char_u *buf, int buflen));
  char_u *replace_termcodes __ARGS((char_u *from, char_u **bufp, int from_part, 
int do_lt, int special));
  int find_term_bykeys __ARGS((char_u *src));
  void show_termcodes __ARGS((void));
--- 50,56 ----
  char_u *get_termcode __ARGS((int i));
  void del_termcode __ARGS((char_u *name));
  void set_mouse_topline __ARGS((win_T *wp));
! int check_termcode __ARGS((int max_offset, char_u *buf, int bufsize, int 
*buflen));
  char_u *replace_termcodes __ARGS((char_u *from, char_u **bufp, int from_part, 
int do_lt, int special));
  int find_term_bykeys __ARGS((char_u *src));
  void show_termcodes __ARGS((void));
*** ../vim-7.3.430/src/version.c        2012-02-05 20:08:30.000000000 +0100
--- src/version.c       2012-02-05 22:03:43.000000000 +0100
***************
*** 716,717 ****
--- 716,719 ----
  {   /* Add new patch number below this line */
+ /**/
+     431,
  /**/

-- 
"You know, it's at times like this when I'm trapped in a Vogon airlock with
a man from Betelgeuse and about to die of asphyxiation in deep space that I
really wish I'd listened to what my mother told me when I was young!"
"Why, what did she tell you?"
"I don't know, I didn't listen!"
                -- Arthur Dent and Ford Prefect in Douglas Adams'
                   "The Hitchhiker's Guide to the Galaxy"

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Raspunde prin e-mail lui