Patch 8.1.0439
Problem: Recursive use of getcmdline() still not protected.
Solution: Instead of saving the command buffer when making a call which may
cause recursiveness, save the buffer when actually being called
recursively.
Files: src/ex_getln.c, src/proto/ex_getln.pro, src/getchar.c, src/main.c
*** ../vim-8.1.0438/src/ex_getln.c 2018-09-25 22:27:31.958075001 +0200
--- src/ex_getln.c 2018-09-30 17:09:47.106527162 +0200
***************
*** 44,56 ****
# endif
};
! /* The current cmdline_info. It is initialized in getcmdline() and after that
! * used by other functions. When invoking getcmdline() recursively it needs
! * to be saved with save_cmdline() and restored with restore_cmdline().
! * TODO: make it local to getcmdline() and pass it around. */
static struct cmdline_info ccline;
! static int cmd_showtail; /* Only show path tail in lists ? */
#ifdef FEAT_EVAL
static int new_cmdpos; /* position set by set_cmdline_pos() */
--- 44,55 ----
# endif
};
! // The current cmdline_info. It is initialized in getcmdline() and after that
! // used by other functions. When invoking getcmdline() recursively it needs
! // to be saved with save_cmdline() and restored with restore_cmdline().
static struct cmdline_info ccline;
! static int cmd_showtail; /* Only show path tail in lists ? */
#ifdef FEAT_EVAL
static int new_cmdpos; /* position set by set_cmdline_pos() */
***************
*** 91,96 ****
--- 90,96 ----
static int cmd_fkmap = 0; /* Farsi mapping during command line */
#endif
+ static char_u *getcmdline_int(int firstc, long count, int indent, int
init_ccline);
static int cmdline_charsize(int idx);
static void set_cmdspos(void);
static void set_cmdspos_cursor(void);
***************
*** 463,469 ****
int skiplen, patlen;
int found; // do_search() result
pos_T end_pos;
- struct cmdline_info save_ccline;
#ifdef FEAT_RELTIME
proftime_T tm;
#endif
--- 463,468 ----
***************
*** 601,609 ****
if (p_ru && curwin->w_status_height > 0)
curwin->w_redr_status = TRUE;
- save_cmdline(&save_ccline);
update_screen(SOME_VALID);
- restore_cmdline(&save_ccline);
restore_last_search_pattern();
// Leave it at the end to make CTRL-R CTRL-W work. But not when beyond
the
--- 600,606 ----
***************
*** 800,807 ****
char_u *
getcmdline(
int firstc,
! long count UNUSED, /* only used for incremental search */
! int indent) /* indent for inside conditionals */
{
int c;
int i;
--- 797,814 ----
char_u *
getcmdline(
int firstc,
! long count, // only used for incremental search
! int indent) // indent for inside conditionals
! {
! return getcmdline_int(firstc, count, indent, TRUE);
! }
!
! static char_u *
! getcmdline_int(
! int firstc,
! long count UNUSED, // only used for incremental search
! int indent, // indent for inside conditionals
! int init_ccline) // clear ccline first
{
int c;
int i;
***************
*** 832,845 ****
#endif
expand_T xpc;
long *b_im_ptr = NULL;
- #if defined(FEAT_WILDMENU) || defined(FEAT_EVAL)
- /* Everything that may work recursively should save and restore the
- * current command line in save_ccline. That includes update_screen(), a
- * custom status line may invoke ":normal". */
struct cmdline_info save_ccline;
! #endif
int cmdline_type;
#ifdef FEAT_EVAL
if (firstc == -1)
{
--- 839,858 ----
#endif
expand_T xpc;
long *b_im_ptr = NULL;
struct cmdline_info save_ccline;
! int did_save_ccline = FALSE;
int cmdline_type;
+ if (ccline.cmdbuff != NULL)
+ {
+ // Being called recursively. Since ccline is global, we need to save
+ // the current buffer and restore it when returning.
+ save_cmdline(&save_ccline);
+ did_save_ccline = TRUE;
+ }
+ if (init_ccline)
+ vim_memset(&ccline, 0, sizeof(struct cmdline_info));
+
#ifdef FEAT_EVAL
if (firstc == -1)
{
***************
*** 868,874 ****
/* alloc initial ccline.cmdbuff */
alloc_cmdbuff(exmode_active ? 250 : indent + 1);
if (ccline.cmdbuff == NULL)
! return NULL; /* out of memory */
ccline.cmdlen = ccline.cmdpos = 0;
ccline.cmdbuff[0] = NUL;
sb_text_start_cmdline();
--- 881,887 ----
/* alloc initial ccline.cmdbuff */
alloc_cmdbuff(exmode_active ? 250 : indent + 1);
if (ccline.cmdbuff == NULL)
! goto theend; // out of memory
ccline.cmdlen = ccline.cmdpos = 0;
ccline.cmdbuff[0] = NUL;
sb_text_start_cmdline();
***************
*** 1125,1133 ****
p_ls = save_p_ls;
p_wmh = save_p_wmh;
last_status(FALSE);
- save_cmdline(&save_ccline);
update_screen(VALID); /* redraw the screen NOW */
- restore_cmdline(&save_ccline);
redrawcmd();
save_p_ls = -1;
}
--- 1138,1144 ----
***************
*** 1333,1351 ****
else
new_cmdpos = ccline.cmdpos;
- save_cmdline(&save_ccline);
c = get_expr_register();
- restore_cmdline(&save_ccline);
if (c == '=')
{
/* Need to save and restore ccline. And set "textlock"
* to avoid nasty things like going to another buffer when
* evaluating an expression. */
- save_cmdline(&save_ccline);
++textlock;
p = get_expr_line();
--textlock;
- restore_cmdline(&save_ccline);
if (p != NULL)
{
--- 1344,1358 ----
***************
*** 1812,1822 ****
c = ESC;
}
else
- {
- save_cmdline(&save_ccline);
c = get_expr_register();
- restore_cmdline(&save_ccline);
- }
}
#endif
if (c != ESC) /* use ESC to cancel inserting register */
--- 1819,1825 ----
***************
*** 2187,2193 ****
int len;
int old_firstc;
! vim_free(ccline.cmdbuff);
xpc.xp_context = EXPAND_NOTHING;
if (hiscnt == hislen)
p = lookfor; /* back to the old one */
--- 2190,2196 ----
int len;
int old_firstc;
! VIM_CLEAR(ccline.cmdbuff);
xpc.xp_context = EXPAND_NOTHING;
if (hiscnt == hislen)
p = lookfor; /* back to the old one */
***************
*** 2486,2496 ****
#endif
sb_text_end_cmdline();
{
char_u *p = ccline.cmdbuff;
! /* Make ccline empty, getcmdline() may try to use it. */
! ccline.cmdbuff = NULL;
return p;
}
}
--- 2489,2502 ----
#endif
sb_text_end_cmdline();
+ theend:
{
char_u *p = ccline.cmdbuff;
! if (did_save_ccline)
! restore_cmdline(&save_ccline);
! else
! ccline.cmdbuff = NULL;
return p;
}
}
***************
*** 2512,2521 ****
{
char_u *s;
struct cmdline_info save_ccline;
int msg_col_save = msg_col;
int msg_silent_save = msg_silent;
! save_cmdline(&save_ccline);
ccline.cmdprompt = prompt;
ccline.cmdattr = attr;
# ifdef FEAT_EVAL
--- 2518,2535 ----
{
char_u *s;
struct cmdline_info save_ccline;
+ int did_save_ccline = FALSE;
int msg_col_save = msg_col;
int msg_silent_save = msg_silent;
! if (ccline.cmdbuff != NULL)
! {
! // Save the values of the current cmdline and restore them below.
! save_cmdline(&save_ccline);
! did_save_ccline = TRUE;
! }
!
! vim_memset(&ccline, 0, sizeof(struct cmdline_info));
ccline.cmdprompt = prompt;
ccline.cmdattr = attr;
# ifdef FEAT_EVAL
***************
*** 2524,2531 ****
ccline.input_fn = (firstc == '@');
# endif
msg_silent = 0;
! s = getcmdline(firstc, 1L, 0);
! restore_cmdline(&save_ccline);
msg_silent = msg_silent_save;
/* Restore msg_col, the prompt from input() may have changed it.
* But only if called recursively and the commandline is therefore being
--- 2538,2548 ----
ccline.input_fn = (firstc == '@');
# endif
msg_silent = 0;
! s = getcmdline_int(firstc, 1L, 0, FALSE);
!
! if (did_save_ccline)
! restore_cmdline(&save_ccline);
!
msg_silent = msg_silent_save;
/* Restore msg_col, the prompt from input() may have changed it.
* But only if called recursively and the commandline is therefore being
***************
*** 3121,3127 ****
/*
* Allocate a new command line buffer.
* Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
- * Returns the new value of ccline.cmdbuff and ccline.cmdbufflen.
*/
static void
alloc_cmdbuff(int len)
--- 3138,3143 ----
***************
*** 3542,3550 ****
}
*ccp = prev_ccline;
prev_ccline = ccline;
! ccline.cmdbuff = NULL;
! ccline.cmdprompt = NULL;
! ccline.xpc = NULL;
}
/*
--- 3558,3564 ----
}
*ccp = prev_ccline;
prev_ccline = ccline;
! ccline.cmdbuff = NULL; // signal that ccline is not in use
}
/*
***************
*** 3557,3593 ****
prev_ccline = *ccp;
}
- #if defined(FEAT_EVAL) || defined(PROTO)
- /*
- * Save the command line into allocated memory. Returns a pointer to be
- * passed to restore_cmdline_alloc() later.
- * Returns NULL when failed.
- */
- char_u *
- save_cmdline_alloc(void)
- {
- struct cmdline_info *p;
-
- p = (struct cmdline_info *)alloc((unsigned)sizeof(struct cmdline_info));
- if (p != NULL)
- save_cmdline(p);
- return (char_u *)p;
- }
-
- /*
- * Restore the command line from the return value of save_cmdline_alloc().
- */
- void
- restore_cmdline_alloc(char_u *p)
- {
- if (p != NULL)
- {
- restore_cmdline((struct cmdline_info *)p);
- vim_free(p);
- }
- }
- #endif
-
/*
* Paste a yank register into the command line.
* Used by CTRL-R command in command-line mode.
--- 3571,3576 ----
***************
*** 3606,3612 ****
char_u *arg;
char_u *p;
int allocated;
- struct cmdline_info save_ccline;
/* check for valid regname; also accept special characters for CTRL-R in
* the command line */
--- 3589,3594 ----
***************
*** 3625,3637 ****
regname = may_get_selection(regname);
#endif
! /* Need to save and restore ccline. And set "textlock" to avoid nasty
! * things like going to another buffer when evaluating an expression. */
! save_cmdline(&save_ccline);
++textlock;
i = get_spec_reg(regname, &arg, &allocated, TRUE);
--textlock;
- restore_cmdline(&save_ccline);
if (i)
{
--- 3607,3617 ----
regname = may_get_selection(regname);
#endif
! // Need to set "textlock" to avoid nasty things like going to another
! // buffer when evaluating an expression.
++textlock;
i = get_spec_reg(regname, &arg, &allocated, TRUE);
--textlock;
if (i)
{
***************
*** 5601,5607 ****
sctx_T save_current_sctx = current_sctx;
char_u *pat = NULL;
void *ret;
- struct cmdline_info save_ccline;
if (xp->xp_arg == NULL || xp->xp_arg[0] == '\0' || xp->xp_line == NULL)
return NULL;
--- 5581,5586 ----
***************
*** 5624,5638 ****
args[2].vval.v_number = xp->xp_col;
args[3].v_type = VAR_UNKNOWN;
- /* Save the cmdline, we don't know what the function may do. */
- save_ccline = ccline;
- ccline.cmdbuff = NULL;
- ccline.cmdprompt = NULL;
current_sctx = xp->xp_script_ctx;
ret = user_expand_func(xp->xp_arg, 3, args);
- ccline = save_ccline;
current_sctx = save_current_sctx;
if (ccline.cmdbuff != NULL)
ccline.cmdbuff[ccline.cmdlen] = keep;
--- 5603,5612 ----
***************
*** 6481,6487 ****
#if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO)
/*
! * Get pointer to the command line info to use. cmdline_paste() may clear
* ccline and put the previous value in prev_ccline.
*/
static struct cmdline_info *
--- 6455,6461 ----
#if defined(FEAT_EVAL) || defined(FEAT_CMDWIN) || defined(PROTO)
/*
! * Get pointer to the command line info to use. save_ccline() may clear
* ccline and put the previous value in prev_ccline.
*/
static struct cmdline_info *
***************
*** 7072,7077 ****
--- 7046,7057 ----
}
}
+ void
+ cmdline_init(void)
+ {
+ vim_memset(&ccline, 0, sizeof(struct cmdline_info));
+ }
+
/*
* Write history to viminfo file in "fp".
* When "merge" is TRUE merge history lines with a previously read viminfo
***************
*** 7238,7244 ****
static int
open_cmdwin(void)
{
- struct cmdline_info save_ccline;
bufref_T old_curbuf;
win_T *old_curwin = curwin;
bufref_T bufref;
--- 7218,7223 ----
***************
*** 7355,7363 ****
invalidate_botline();
redraw_later(SOME_VALID);
- /* Save the command line info, can be used recursively. */
- save_cmdline(&save_ccline);
-
/* No Ex mode here! */
exmode_active = 0;
--- 7334,7339 ----
***************
*** 7394,7403 ****
KeyTyped = save_KeyTyped;
# endif
- /* Restore the command line info. */
- restore_cmdline(&save_ccline);
cmdwin_type = 0;
-
exmode_active = save_exmode;
/* Safety check: The old window or buffer was deleted: It's a bug when
--- 7370,7376 ----
*** ../vim-8.1.0438/src/proto/ex_getln.pro 2018-05-17 13:52:35.000000000
+0200
--- src/proto/ex_getln.pro 2018-09-30 15:11:35.810356311 +0200
***************
*** 15,22 ****
void putcmdline(int c, int shift);
void unputcmdline(void);
int put_on_cmdline(char_u *str, int len, int redraw);
- char_u *save_cmdline_alloc(void);
- void restore_cmdline_alloc(char_u *p);
void cmdline_paste_str(char_u *s, int literally);
void redrawcmdline(void);
void redrawcmdline_ex(int do_compute_cmdrow);
--- 15,20 ----
***************
*** 54,59 ****
--- 52,58 ----
int read_viminfo_history(vir_T *virp, int writing);
void handle_viminfo_history(garray_T *values, int writing);
void finish_viminfo_history(vir_T *virp);
+ void cmdline_init(void);
void write_viminfo_history(FILE *fp, int merge);
void cmd_pchar(int c, int offset);
int cmd_gchar(int offset);
*** ../vim-8.1.0438/src/getchar.c 2018-09-10 21:04:09.868392665 +0200
--- src/getchar.c 2018-09-30 14:32:29.424816910 +0200
***************
*** 4666,4672 ****
char_u *res;
char_u *p;
char_u *expr;
- char_u *save_cmd;
pos_T save_cursor;
int save_msg_col;
int save_msg_row;
--- 4666,4671 ----
***************
*** 4678,4690 ****
return NULL;
vim_unescape_csi(expr);
- save_cmd = save_cmdline_alloc();
- if (save_cmd == NULL)
- {
- vim_free(expr);
- return NULL;
- }
-
/* Forbid changing text or using ":normal" to avoid most of the bad side
* effects. Also restore the cursor position. */
++textlock;
--- 4677,4682 ----
***************
*** 4700,4706 ****
msg_col = save_msg_col;
msg_row = save_msg_row;
- restore_cmdline_alloc(save_cmd);
vim_free(expr);
if (p == NULL)
--- 4692,4697 ----
*** ../vim-8.1.0438/src/main.c 2018-09-16 14:10:28.300323360 +0200
--- src/main.c 2018-09-30 15:10:50.358720630 +0200
***************
*** 929,934 ****
--- 929,935 ----
void
common_init(mparm_T *paramp)
{
+ cmdline_init();
#ifdef FEAT_MBYTE
(void)mb_init(); /* init mb_bytelen_tab[] to ones */
*** ../vim-8.1.0438/src/version.c 2018-09-28 23:09:50.558463030 +0200
--- src/version.c 2018-09-30 17:07:43.183446960 +0200
***************
*** 796,797 ****
--- 796,799 ----
{ /* Add new patch number below this line */
+ /**/
+ 439,
/**/
--
hundred-and-one symptoms of being an internet addict:
124. You begin conversations with, "Who is your internet service provider?"
/// 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
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.