mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	fix(options): missing error check for global 'scl' and 'winhl' (#30919)
This commit is contained in:
		@@ -1816,12 +1816,22 @@ void check_blending(win_T *wp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Handle setting `winhighlight' in window "wp"
 | 
			
		||||
bool parse_winhl_opt(win_T *wp)
 | 
			
		||||
///
 | 
			
		||||
/// @param winhl  when NULL: use "wp->w_p_winhl"
 | 
			
		||||
/// @param wp     when NULL: only parse "winhl"
 | 
			
		||||
///
 | 
			
		||||
/// @return  whether the option value is valid.
 | 
			
		||||
bool parse_winhl_opt(const char *winhl, win_T *wp)
 | 
			
		||||
{
 | 
			
		||||
  const char *p = wp->w_p_winhl;
 | 
			
		||||
  const char *p = empty_string_option;
 | 
			
		||||
  if (winhl != NULL) {
 | 
			
		||||
    p = winhl;
 | 
			
		||||
  } else if (wp != NULL) {
 | 
			
		||||
    p = wp->w_p_winhl;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!*p) {
 | 
			
		||||
    if (wp->w_ns_hl_winhl && wp->w_ns_hl == wp->w_ns_hl_winhl) {
 | 
			
		||||
    if (wp != NULL && wp->w_ns_hl_winhl && wp->w_ns_hl == wp->w_ns_hl_winhl) {
 | 
			
		||||
      wp->w_ns_hl = 0;
 | 
			
		||||
      wp->w_hl_needs_update = true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1829,24 +1839,27 @@ bool parse_winhl_opt(win_T *wp)
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int ns_hl = 0;
 | 
			
		||||
  if (wp != NULL) {
 | 
			
		||||
    if (wp->w_ns_hl_winhl == 0) {
 | 
			
		||||
      wp->w_ns_hl_winhl = (int)nvim_create_namespace(NULL_STRING);
 | 
			
		||||
    } else {
 | 
			
		||||
    // namespace already exist. invalidate existing items
 | 
			
		||||
      // Namespace already exists. Invalidate existing items.
 | 
			
		||||
      DecorProvider *dp = get_decor_provider(wp->w_ns_hl_winhl, true);
 | 
			
		||||
      dp->hl_valid++;
 | 
			
		||||
    }
 | 
			
		||||
    wp->w_ns_hl = wp->w_ns_hl_winhl;
 | 
			
		||||
  int ns_hl = wp->w_ns_hl;
 | 
			
		||||
    ns_hl = wp->w_ns_hl;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  while (*p) {
 | 
			
		||||
    char *colon = strchr(p, ':');
 | 
			
		||||
    const char *colon = strchr(p, ':');
 | 
			
		||||
    if (!colon) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    size_t nlen = (size_t)(colon - p);
 | 
			
		||||
    char *hi = colon + 1;
 | 
			
		||||
    char *commap = xstrchrnul(hi, ',');
 | 
			
		||||
    const char *hi = colon + 1;
 | 
			
		||||
    const char *commap = xstrchrnul(hi, ',');
 | 
			
		||||
    size_t len = (size_t)(commap - hi);
 | 
			
		||||
    int hl_id = len ? syn_check_group(hi, len) : -1;
 | 
			
		||||
    if (hl_id == 0) {
 | 
			
		||||
@@ -1857,14 +1870,18 @@ bool parse_winhl_opt(win_T *wp)
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (wp != NULL) {
 | 
			
		||||
      HlAttrs attrs = HLATTRS_INIT;
 | 
			
		||||
      attrs.rgb_ae_attr |= HL_GLOBAL;
 | 
			
		||||
      ns_hl_def(ns_hl, hl_id_link, attrs, hl_id, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    p = *commap ? commap + 1 : "";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (wp != NULL) {
 | 
			
		||||
    wp->w_hl_needs_update = true;
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2281,7 +2298,7 @@ static const char *did_set_number_relativenumber(optset_T *args)
 | 
			
		||||
    // When 'relativenumber'/'number' is changed and 'statuscolumn' is set, reset width.
 | 
			
		||||
    win->w_nrwidth_line_count = 0;
 | 
			
		||||
  }
 | 
			
		||||
  check_signcolumn(win);
 | 
			
		||||
  check_signcolumn(NULL, win);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -5116,10 +5133,10 @@ void didset_window_options(win_T *wp, bool valid_cursor)
 | 
			
		||||
  fill_culopt_flags(NULL, wp);
 | 
			
		||||
  set_chars_option(wp, wp->w_p_fcs, kFillchars, true, NULL, 0);
 | 
			
		||||
  set_chars_option(wp, wp->w_p_lcs, kListchars, true, NULL, 0);
 | 
			
		||||
  parse_winhl_opt(wp);  // sets w_hl_needs_update also for w_p_winbl
 | 
			
		||||
  parse_winhl_opt(NULL, wp);  // sets w_hl_needs_update also for w_p_winbl
 | 
			
		||||
  check_blending(wp);
 | 
			
		||||
  set_winbar_win(wp, false, valid_cursor);
 | 
			
		||||
  check_signcolumn(wp);
 | 
			
		||||
  check_signcolumn(NULL, wp);
 | 
			
		||||
  wp->w_grid_alloc.blending = wp->w_p_winbl > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -283,15 +283,27 @@ static bool valid_filetype(const char *val)
 | 
			
		||||
 | 
			
		||||
/// Handle setting 'signcolumn' for value 'val'. Store minimum and maximum width.
 | 
			
		||||
///
 | 
			
		||||
/// @param wcl  when NULL: use "wp->w_p_scl"
 | 
			
		||||
/// @param wp   when NULL: only parse "scl"
 | 
			
		||||
///
 | 
			
		||||
/// @return OK when the value is valid, FAIL otherwise
 | 
			
		||||
int check_signcolumn(win_T *wp)
 | 
			
		||||
int check_signcolumn(char *scl, win_T *wp)
 | 
			
		||||
{
 | 
			
		||||
  char *val = wp->w_p_scl;
 | 
			
		||||
  char *val = empty_string_option;
 | 
			
		||||
  if (scl != NULL) {
 | 
			
		||||
    val = scl;
 | 
			
		||||
  } else if (wp != NULL) {
 | 
			
		||||
    val = wp->w_p_scl;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (*val == NUL) {
 | 
			
		||||
    return FAIL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (check_opt_strings(val, p_scl_values, false) == OK) {
 | 
			
		||||
    if (wp == NULL) {
 | 
			
		||||
      return OK;
 | 
			
		||||
    }
 | 
			
		||||
    if (!strncmp(val, "no", 2)) {  // no
 | 
			
		||||
      wp->w_minscwidth = wp->w_maxscwidth = SCL_NO;
 | 
			
		||||
    } else if (!strncmp(val, "nu", 2) && (wp->w_p_nu || wp->w_p_rnu)) {  // number
 | 
			
		||||
@@ -321,6 +333,9 @@ int check_signcolumn(win_T *wp)
 | 
			
		||||
    if (min < 1 || max < 2 || min > 8 || min >= max) {
 | 
			
		||||
      return FAIL;
 | 
			
		||||
    }
 | 
			
		||||
    if (wp == NULL) {
 | 
			
		||||
      return OK;
 | 
			
		||||
    }
 | 
			
		||||
    wp->w_minscwidth = min;
 | 
			
		||||
    wp->w_maxscwidth = max;
 | 
			
		||||
  }
 | 
			
		||||
@@ -2099,8 +2114,9 @@ int expand_set_showcmdloc(optexpand_T *args, int *numMatches, char ***matches)
 | 
			
		||||
const char *did_set_signcolumn(optset_T *args)
 | 
			
		||||
{
 | 
			
		||||
  win_T *win = (win_T *)args->os_win;
 | 
			
		||||
  char **varp = (char **)args->os_varp;
 | 
			
		||||
  const char *oldval = args->os_oldval.string.data;
 | 
			
		||||
  if (check_signcolumn(win) != OK) {
 | 
			
		||||
  if (check_signcolumn(*varp, varp == &win->w_p_scl ? win : NULL) != OK) {
 | 
			
		||||
    return e_invarg;
 | 
			
		||||
  }
 | 
			
		||||
  // When changing the 'signcolumn' to or from 'number', recompute the
 | 
			
		||||
@@ -2568,7 +2584,8 @@ const char *did_set_winbar(optset_T *args)
 | 
			
		||||
const char *did_set_winhighlight(optset_T *args)
 | 
			
		||||
{
 | 
			
		||||
  win_T *win = (win_T *)args->os_win;
 | 
			
		||||
  if (!parse_winhl_opt(win)) {
 | 
			
		||||
  char **varp = (char **)args->os_varp;
 | 
			
		||||
  if (!parse_winhl_opt(*varp, varp == &win->w_p_winhl ? win : NULL)) {
 | 
			
		||||
    return e_invarg;
 | 
			
		||||
  }
 | 
			
		||||
  return NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +137,7 @@ void win_set_minimal_style(win_T *wp)
 | 
			
		||||
                   ? xstrdup("EndOfBuffer:")
 | 
			
		||||
                   : concat_str(old, ",EndOfBuffer:"));
 | 
			
		||||
  free_string_option(old);
 | 
			
		||||
  parse_winhl_opt(wp);
 | 
			
		||||
  parse_winhl_opt(NULL, wp);
 | 
			
		||||
 | 
			
		||||
  // signcolumn: use 'auto'
 | 
			
		||||
  if (wp->w_p_scl[0] != 'a' || strlen(wp->w_p_scl) >= 8) {
 | 
			
		||||
 
 | 
			
		||||
@@ -45,8 +45,6 @@ endwhile
 | 
			
		||||
let skip_setglobal_reasons = #{
 | 
			
		||||
      \ iminsert: 'The global value is always overwritten by the local value',
 | 
			
		||||
      \ imsearch: 'The global value is always overwritten by the local value',
 | 
			
		||||
      \ signcolumn:	'TODO(nvim): fix missing error handling for setglobal',
 | 
			
		||||
      \ winhighlight:	'TODO(nvim): fix missing error handling for setglobal',
 | 
			
		||||
      \}
 | 
			
		||||
 | 
			
		||||
" Script header.
 | 
			
		||||
@@ -92,12 +90,13 @@ let test_values = {
 | 
			
		||||
      \		'noinsert', 'noselect', 'fuzzy', 'menu,longest'],
 | 
			
		||||
      \		['xxx', 'menu,,,longest,']],
 | 
			
		||||
      \ 'encoding': [['utf8'], []],
 | 
			
		||||
      \ 'foldcolumn': [[0, 1, 4], [-1, 13, 999]],
 | 
			
		||||
      \ 'foldcolumn': [[0, 1, 4, 'auto', 'auto:1', 'auto:9'], [-1, 13, 999]],
 | 
			
		||||
      \ 'foldlevel': [[0, 100], [-1, '']],
 | 
			
		||||
      \ 'highlight': [[&highlight], []],
 | 
			
		||||
      \ 'iminsert': [[0, 1], [-1, 2, 3, 999]],
 | 
			
		||||
      \ 'imsearch': [[-1, 0, 1], [-2, 2, 3, 999]],
 | 
			
		||||
      \ 'signcolumn': [['auto', 'no', 'yes', 'number'], ['', 'xxx', 'no,yes']],
 | 
			
		||||
      \ 'signcolumn': [['auto', 'no', 'yes', 'number', 'yes:1', 'auto:1-9'],
 | 
			
		||||
      \		['', 'xxx', 'no,yes', 'auto:0-9', 'auto:9-1', 'auto:1-@']],
 | 
			
		||||
      \ 'writedelay': [[0, 100], [-1, '']],
 | 
			
		||||
      \
 | 
			
		||||
      "\ boolean options
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user