vim-patch:8.2.3410: crash with linebreak, listchars and large tabstop

Problem:    Crash with linebreak, listchars and large tabstop.
Solution:   Account for different size listchars for a tab. (closes vim/vim#8841)
89a54b413a
This commit is contained in:
zeertzjq 2022-01-21 18:16:16 +08:00
parent 296b8fbe3b
commit cb39c825c4
2 changed files with 40 additions and 25 deletions

View File

@ -3720,41 +3720,46 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
tab_len += n_extra - tab_len; tab_len += n_extra - tab_len;
} }
// if n_extra > 0, it gives the number of chars // If n_extra > 0, it gives the number of chars
// to use for a tab, else we need to calculate the width // to use for a tab, else we need to calculate the width
// for a tab // for a tab.
int len = (tab_len * utf_char2len(wp->w_p_lcs_chars.tab2)); int len = (tab_len * utf_char2len(wp->w_p_lcs_chars.tab2));
if (wp->w_p_lcs_chars.tab3) {
len += utf_char2len(wp->w_p_lcs_chars.tab3);
}
if (n_extra > 0) { if (n_extra > 0) {
len += n_extra - tab_len; len += n_extra - tab_len;
} }
c = wp->w_p_lcs_chars.tab1; c = wp->w_p_lcs_chars.tab1;
p = xmalloc(len + 1); p = xmalloc(len + 1);
memset(p, ' ', len); if (p == NULL) {
p[len] = NUL; n_extra = 0;
xfree(p_extra_free); } else {
p_extra_free = p; memset(p, ' ', len);
for (i = 0; i < tab_len; i++) { p[len] = NUL;
if (*p == NUL) { xfree(p_extra_free);
tab_len = i; p_extra_free = p;
break; for (i = 0; i < tab_len; i++) {
} if (*p == NUL) {
int lcs = wp->w_p_lcs_chars.tab2; tab_len = i;
break;
}
int lcs = wp->w_p_lcs_chars.tab2;
// if tab3 is given, need to change the char // if tab3 is given, use it for the last char
// for tab if (wp->w_p_lcs_chars.tab3 && i == tab_len - 1) {
if (wp->w_p_lcs_chars.tab3 && i == tab_len - 1) { lcs = wp->w_p_lcs_chars.tab3;
lcs = wp->w_p_lcs_chars.tab3; }
p += utf_char2bytes(lcs, p);
n_extra += utf_char2len(lcs) - (saved_nextra > 0 ? 1 : 0);
} }
utf_char2bytes(lcs, p); p_extra = p_extra_free;
p += utf_char2len(lcs);
n_extra += utf_char2len(lcs) - (saved_nextra > 0 ? 1 : 0);
}
p_extra = p_extra_free;
// n_extra will be increased by FIX_FOX_BOGUSCOLS // n_extra will be increased by FIX_FOX_BOGUSCOLS
// macro below, so need to adjust for that here // macro below, so need to adjust for that here
if (vcol_off > 0) { if (vcol_off > 0) {
n_extra -= vcol_off; n_extra -= vcol_off;
}
} }
} }

View File

@ -69,6 +69,16 @@ func Test_nolinebreak_with_list()
call s:close_windows() call s:close_windows()
endfunc endfunc
" this was causing a crash
func Test_linebreak_with_list_and_tabs()
set linebreak list listchars=tab:⇤\ ⇥ tabstop=100
new
call setline(1, "\t\t\ttext")
redraw
bwipe!
set nolinebreak nolist listchars&vim tabstop=8
endfunc
func Test_linebreak_with_nolist() func Test_linebreak_with_nolist()
call s:test_windows('setl nolist') call s:test_windows('setl nolist')
call setline(1, "\t*mask = nil;") call setline(1, "\t*mask = nil;")