home *** CD-ROM | disk | FTP | other *** search
- To: vim-dev@vim.org
- Subject: Patch 7.2.080
- Fcc: outbox
- From: Bram Moolenaar <Bram@moolenaar.net>
- Mime-Version: 1.0
- Content-Type: text/plain; charset=ISO-8859-1
- Content-Transfer-Encoding: 8bit
- ------------
-
- Patch 7.2.080
- Problem: When typing a composing character just after starting completion
- may access memory before its allocation point. (Dominique Pelle)
- Solution: Don't delete before the completion start column. Add extra checks
- for the offset not being negative.
- Files: src/edit.c
-
-
- *** ../vim-7.2.079/src/edit.c Wed Aug 6 18:56:55 2008
- --- src/edit.c Tue Jan 13 12:05:57 2009
- ***************
- *** 147,152 ****
- --- 147,153 ----
- static int ins_compl_bs __ARGS((void));
- static void ins_compl_new_leader __ARGS((void));
- static void ins_compl_addleader __ARGS((int c));
- + static int ins_compl_len __ARGS((void));
- static void ins_compl_restart __ARGS((void));
- static void ins_compl_set_original_text __ARGS((char_u *str));
- static void ins_compl_addfrommatch __ARGS((void));
- ***************
- *** 197,203 ****
- static void mb_replace_pop_ins __ARGS((int cc));
- #endif
- static void replace_flush __ARGS((void));
- ! static void replace_do_bs __ARGS((void));
- #ifdef FEAT_CINDENT
- static int cindent_on __ARGS((void));
- #endif
- --- 198,205 ----
- static void mb_replace_pop_ins __ARGS((int cc));
- #endif
- static void replace_flush __ARGS((void));
- ! static void replace_do_bs __ARGS((int limit_col));
- ! static int del_char_after_col __ARGS((int limit_col));
- #ifdef FEAT_CINDENT
- static int cindent_on __ARGS((void));
- #endif
- ***************
- *** 1933,1938 ****
- --- 1935,1942 ----
- /*
- * Backspace the cursor until the given column. Handles REPLACE and VREPLACE
- * modes correctly. May also be used when not in insert mode at all.
- + * Will attempt not to go before "col" even when there is a composing
- + * character.
- */
- void
- backspace_until_column(col)
- ***************
- *** 1942,1954 ****
- {
- curwin->w_cursor.col--;
- if (State & REPLACE_FLAG)
- ! replace_do_bs();
- ! else
- ! (void)del_char(FALSE);
- }
- }
- #endif
-
- #if defined(FEAT_INS_EXPAND) || defined(PROTO)
- /*
- * CTRL-X pressed in Insert mode.
- --- 1946,1994 ----
- {
- curwin->w_cursor.col--;
- if (State & REPLACE_FLAG)
- ! replace_do_bs(col);
- ! else if (!del_char_after_col(col))
- ! break;
- }
- }
- #endif
-
- + /*
- + * Like del_char(), but make sure not to go before column "limit_col".
- + * Only matters when there are composing characters.
- + * Return TRUE when something was deleted.
- + */
- + static int
- + del_char_after_col(limit_col)
- + int limit_col;
- + {
- + #ifdef FEAT_MBYTE
- + if (enc_utf8 && limit_col >= 0)
- + {
- + int ecol = curwin->w_cursor.col + 1;
- +
- + /* Make sure the cursor is at the start of a character, but
- + * skip forward again when going too far back because of a
- + * composing character. */
- + mb_adjust_cursor();
- + while (curwin->w_cursor.col < limit_col)
- + {
- + int l = utf_ptr2len(ml_get_cursor());
- +
- + if (l == 0) /* end of line */
- + break;
- + curwin->w_cursor.col += l;
- + }
- + if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol)
- + return FALSE;
- + del_bytes((long)(ecol - curwin->w_cursor.col), FALSE, TRUE);
- + }
- + else
- + #endif
- + (void)del_char(FALSE);
- + return TRUE;
- + }
- +
- #if defined(FEAT_INS_EXPAND) || defined(PROTO)
- /*
- * CTRL-X pressed in Insert mode.
- ***************
- *** 2418,2424 ****
- {
- had_match = (curwin->w_cursor.col > compl_col);
- ins_compl_delete();
- ! ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
- ins_redraw(FALSE);
-
- /* When the match isn't there (to avoid matching itself) remove it
- --- 2458,2464 ----
- {
- had_match = (curwin->w_cursor.col > compl_col);
- ins_compl_delete();
- ! ins_bytes(compl_leader + ins_compl_len());
- ins_redraw(FALSE);
-
- /* When the match isn't there (to avoid matching itself) remove it
- ***************
- *** 2470,2476 ****
- *p = NUL;
- had_match = (curwin->w_cursor.col > compl_col);
- ins_compl_delete();
- ! ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
- ins_redraw(FALSE);
-
- /* When the match isn't there (to avoid matching itself) remove it
- --- 2510,2516 ----
- *p = NUL;
- had_match = (curwin->w_cursor.col > compl_col);
- ins_compl_delete();
- ! ins_bytes(compl_leader + ins_compl_len());
- ins_redraw(FALSE);
-
- /* When the match isn't there (to avoid matching itself) remove it
- ***************
- *** 3209,3215 ****
- {
- ins_compl_del_pum();
- ins_compl_delete();
- ! ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
- compl_used_match = FALSE;
-
- if (compl_started)
- --- 3249,3255 ----
- {
- ins_compl_del_pum();
- ins_compl_delete();
- ! ins_bytes(compl_leader + ins_compl_len());
- compl_used_match = FALSE;
-
- if (compl_started)
- ***************
- *** 3264,3269 ****
- --- 3304,3323 ----
- }
-
- /*
- + * Return the length of the completion, from the completion start column to
- + * the cursor column. Making sure it never goes below zero.
- + */
- + static int
- + ins_compl_len()
- + {
- + int off = curwin->w_cursor.col - compl_col;
- +
- + if (off < 0)
- + return 0;
- + return off;
- + }
- +
- + /*
- * Append one character to the match leader. May reduce the number of
- * matches.
- */
- ***************
- *** 3621,3630 ****
- {
- ins_compl_delete();
- if (compl_leader != NULL)
- ! ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
- else if (compl_first_match != NULL)
- ! ins_bytes(compl_orig_text
- ! + curwin->w_cursor.col - compl_col);
- retval = TRUE;
- }
-
- --- 3675,3683 ----
- {
- ins_compl_delete();
- if (compl_leader != NULL)
- ! ins_bytes(compl_leader + ins_compl_len());
- else if (compl_first_match != NULL)
- ! ins_bytes(compl_orig_text + ins_compl_len());
- retval = TRUE;
- }
-
- ***************
- *** 4256,4262 ****
- static void
- ins_compl_insert()
- {
- ! ins_bytes(compl_shown_match->cp_str + curwin->w_cursor.col - compl_col);
- if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
- compl_used_match = FALSE;
- else
- --- 4309,4315 ----
- static void
- ins_compl_insert()
- {
- ! ins_bytes(compl_shown_match->cp_str + ins_compl_len());
- if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
- compl_used_match = FALSE;
- else
- ***************
- *** 4425,4431 ****
- if (!compl_get_longest || compl_used_match)
- ins_compl_insert();
- else
- ! ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
- }
- else
- compl_used_match = FALSE;
- --- 4478,4484 ----
- if (!compl_get_longest || compl_used_match)
- ins_compl_insert();
- else
- ! ins_bytes(compl_leader + ins_compl_len());
- }
- else
- compl_used_match = FALSE;
- ***************
- *** 7123,7131 ****
- * cc == 0: character was inserted, delete it
- * cc > 0: character was replaced, put cc (first byte of original char) back
- * and check for more characters to be put back
- */
- static void
- ! replace_do_bs()
- {
- int cc;
- #ifdef FEAT_VREPLACE
- --- 7176,7187 ----
- * cc == 0: character was inserted, delete it
- * cc > 0: character was replaced, put cc (first byte of original char) back
- * and check for more characters to be put back
- + * When "limit_col" is >= 0, don't delete before this column. Matters when
- + * using composing characters, use del_char_after_col() instead of del_char().
- */
- static void
- ! replace_do_bs(limit_col)
- ! int limit_col;
- {
- int cc;
- #ifdef FEAT_VREPLACE
- ***************
- *** 7153,7159 ****
- #ifdef FEAT_MBYTE
- if (has_mbyte)
- {
- ! del_char(FALSE);
- # ifdef FEAT_VREPLACE
- if (State & VREPLACE_FLAG)
- orig_len = (int)STRLEN(ml_get_cursor());
- --- 7209,7215 ----
- #ifdef FEAT_MBYTE
- if (has_mbyte)
- {
- ! (void)del_char_after_col(limit_col);
- # ifdef FEAT_VREPLACE
- if (State & VREPLACE_FLAG)
- orig_len = (int)STRLEN(ml_get_cursor());
- ***************
- *** 7203,7209 ****
- changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
- }
- else if (cc == 0)
- ! (void)del_char(FALSE);
- }
-
- #ifdef FEAT_CINDENT
- --- 7259,7265 ----
- changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
- }
- else if (cc == 0)
- ! (void)del_char_after_col(limit_col);
- }
-
- #ifdef FEAT_CINDENT
- ***************
- *** 8239,8245 ****
- * Replace mode */
- if (curwin->w_cursor.lnum != Insstart.lnum
- || curwin->w_cursor.col >= Insstart.col)
- ! replace_do_bs();
- }
- else
- (void)del_char(FALSE);
- --- 8295,8301 ----
- * Replace mode */
- if (curwin->w_cursor.lnum != Insstart.lnum
- || curwin->w_cursor.col >= Insstart.col)
- ! replace_do_bs(-1);
- }
- else
- (void)del_char(FALSE);
- ***************
- *** 8556,8562 ****
- break;
- }
- if (State & REPLACE_FLAG)
- ! replace_do_bs();
- else
- {
- #ifdef FEAT_MBYTE
- --- 8612,8618 ----
- break;
- }
- if (State & REPLACE_FLAG)
- ! replace_do_bs(-1);
- else
- {
- #ifdef FEAT_MBYTE
- *** ../vim-7.2.079/src/version.c Tue Jan 6 16:13:42 2009
- --- src/version.c Tue Jan 13 12:25:29 2009
- ***************
- *** 678,679 ****
- --- 678,681 ----
- { /* Add new patch number below this line */
- + /**/
- + 80,
- /**/
-
- --
- At some point in the project somebody will start whining about the need to
- determine the project "requirements". This involves interviewing people who
- don't know what they want but, curiously, know exactly when they need it.
- (Scott Adams - The Dilbert principle)
-
- /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
- /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
- \\\ download, build and distribute -- http://www.A-A-P.org ///
- \\\ help me help AIDS victims -- http://ICCF-Holland.org ///
-