To: vim_dev@googlegroups.com Subject: Patch 7.3.431 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@Moolenaar.net -- 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 ///