# HG changeset patch # User Christian Brabandt # Date 1691791203 -7200 # Node ID 19a9b8fe3b85225bfbdb398863f7ab4987003103 # Parent a59357132983a73ee932cc3aaed84afe2c3b1d57 patch 9.0.1690: popup_create() not aborting on errors Commit: https://github.com/vim/vim/commit/f6cdab3704959379086d6a097fabdf6c55d73779 Author: Christian Brabandt Date: Fri Aug 11 23:42:02 2023 +0200 patch 9.0.1690: popup_create() not aborting on errors Problem: popup_create() not aborting on errors Solution: check for errors in arguments given and abort if an error occurred closes: #12711 Signed-off-by: Christian Brabandt diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -92,19 +92,19 @@ popup_options_one(dict_T *dict, char_u * return n; } - static void + static int set_padding_border(dict_T *dict, int *array, char *name, int max_val) { dictitem_T *di; di = dict_find(dict, (char_u *)name, -1); if (di == NULL) - return; + return OK; if (di->di_tv.v_type != VAR_LIST) { emsg(_(e_list_required)); - return; + return FAIL; } list_T *list = di->di_tv.vval.v_list; @@ -115,7 +115,7 @@ set_padding_border(dict_T *dict, int *ar for (i = 0; i < 4; ++i) array[i] = 1; if (list == NULL) - return; + return OK; CHECK_LIST_MATERIALIZE(list); for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len; @@ -125,6 +125,8 @@ set_padding_border(dict_T *dict, int *ar if (nr >= 0) array[i] = nr > max_val ? max_val : nr; } + + return OK; } /* @@ -713,7 +715,7 @@ popup_highlight_curline(win_T *wp) /* * Shared between popup_create() and f_popup_setoptions(). */ - static void + static int apply_general_options(win_T *wp, dict_T *dict) { dictitem_T *di; @@ -814,14 +816,18 @@ apply_general_options(win_T *wp, dict_T #endif } - set_padding_border(dict, wp->w_popup_padding, "padding", 999); - set_padding_border(dict, wp->w_popup_border, "border", 1); + if (set_padding_border(dict, wp->w_popup_padding, "padding", 999) == FAIL || + set_padding_border(dict, wp->w_popup_border, "border", 1) == FAIL) + return FAIL; di = dict_find(dict, (char_u *)"borderhighlight", -1); if (di != NULL) { if (di->di_tv.v_type != VAR_LIST || di->di_tv.vval.v_list == NULL) + { emsg(_(e_list_required)); + return FAIL; + } else { list_T *list = di->di_tv.vval.v_list; @@ -853,7 +859,10 @@ apply_general_options(win_T *wp, dict_T if (di != NULL) { if (di->di_tv.v_type != VAR_LIST) + { emsg(_(e_list_required)); + return FAIL; + } else { list_T *list = di->di_tv.vval.v_list; @@ -927,7 +936,10 @@ apply_general_options(win_T *wp, dict_T VIM_CLEAR(wp->w_popup_mask_cells); } else + { semsg(_(e_invalid_value_for_argument_str), "mask"); + return FAIL; + } } #if defined(FEAT_TIMERS) @@ -993,23 +1005,25 @@ apply_general_options(win_T *wp, dict_T di = dict_find(dict, (char_u *)"callback", -1); if (di == NULL) - return; + return OK; callback_T callback = get_callback(&di->di_tv); if (callback.cb_name == NULL) - return; + return OK; free_callback(&wp->w_close_cb); set_callback(&wp->w_close_cb, &callback); if (callback.cb_free_name) vim_free(callback.cb_name); + + return OK; } /* * Go through the options in "dict" and apply them to popup window "wp". * "create" is TRUE when creating a new popup window. */ - static void + static int apply_options(win_T *wp, dict_T *dict, int create) { int nr; @@ -1020,7 +1034,8 @@ apply_options(win_T *wp, dict_T *dict, i set_string_option_direct_in_win(wp, (char_u *)"signcolumn", -1, (char_u *)"no", OPT_FREE|OPT_LOCAL, 0); - apply_general_options(wp, dict); + if (apply_general_options(wp, dict) == FAIL) + return FAIL; nr = dict_get_bool(dict, "hidden", FALSE); if (nr > 0) @@ -1041,6 +1056,8 @@ apply_options(win_T *wp, dict_T *dict, i popup_mask_refresh = TRUE; popup_highlight_curline(wp); + + return OK; } /* @@ -2279,8 +2296,14 @@ popup_create(typval_T *argvars, typval_T wp->w_filter_mode = MODE_ALL; if (d != NULL) + { // Deal with options. - apply_options(wp, d, TRUE); + if (apply_options(wp, d, TRUE) == FAIL) + { + (void)popup_close(wp->w_id, FALSE); + return NULL; + } + } #ifdef FEAT_TIMERS if (popup_is_notification(type) && wp->w_popup_timer == NULL) @@ -2992,7 +3015,7 @@ f_popup_setoptions(typval_T *argvars, ty dict = argvars[1].vval.v_dict; old_firstline = wp->w_firstline; - apply_options(wp, dict, FALSE); + (void)apply_options(wp, dict, FALSE); if (old_firstline != wp->w_firstline) redraw_win_later(wp, UPD_NOT_VALID); diff --git a/src/testdir/dumps/Test_popupwin_with_error_1.dump b/src/testdir/dumps/Test_popupwin_with_error_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_popupwin_with_error_1.dump @@ -0,0 +1,20 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|E+0#ffffff16#e000002|7|1|4|:| |L|i|s|t| |r|e|q|u|i|r|e|d| +0#0000000#ffffff0@37|0|,|0|-|1| @8|A|l@1| diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -4179,5 +4179,22 @@ func Test_term_popup_bufline() call StopVimInTerminal(buf) endfunc +func Test_popupwin_with_error() + CheckScreendump + + let lines =<< trim END + let options = {'border': 'ERROR', 'line': 1, 'col': 1, 'minwidth': &columns, 'title': 'TITLE'} + + END + "call popup_create('Hello world!', options) + call writefile(lines, 'XtestPopupError', 'D') + let buf = RunVimInTerminal('-S XtestPopupError', {}) + call term_sendkeys(buf, ":call popup_create('Hello world!', options)\") + call VerifyScreenDump(buf, 'Test_popupwin_with_error_1', {}) + + " clean up + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1690, +/**/ 1689, /**/ 1688,