From: Christian Brabandt Date: Fri, 11 Aug 2023 21:42:02 +0000 (+0200) Subject: patch 9.0.1690: popup_create() not aborting on errors X-Git-Tag: v9.0.1690 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f6cdab3704959379086d6a097fabdf6c55d73779;p=thirdparty%2Fvim.git 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 index a0d33fd0bb..9f76cb16b6 100644 --- a/src/popupwin.c +++ b/src/popupwin.c @@ -92,19 +92,19 @@ popup_options_one(dict_T *dict, char_u *key) 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 *array, char *name, int max_val) 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 *array, char *name, int max_val) 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 *dict) #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 *dict) 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 *dict) 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 *dict) 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, int create) 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, int create) popup_mask_refresh = TRUE; popup_highlight_curline(wp); + + return OK; } /* @@ -2279,8 +2296,14 @@ popup_create(typval_T *argvars, typval_T *rettv, create_type_T type) 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, typval_T *rettv UNUSED) 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 index 0000000000..be9be327bb --- /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 index 7e1a0fca86..c0842f45a2 100644 --- 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 index 54a43765e7..d8b9f0ef98 100644 --- a/src/version.c +++ b/src/version.c @@ -695,6 +695,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1690, /**/ 1689, /**/