0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

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 #8841)
This commit is contained in:
Bram Moolenaar
2021-09-07 20:45:31 +02:00
parent 65b6056659
commit 89a54b413a
3 changed files with 47 additions and 30 deletions

View File

@@ -2109,55 +2109,60 @@ win_line(
int i; int i;
int saved_nextra = n_extra; int saved_nextra = n_extra;
#ifdef FEAT_CONCEAL # ifdef FEAT_CONCEAL
if (vcol_off > 0) if (vcol_off > 0)
// there are characters to conceal // there are characters to conceal
tab_len += vcol_off; tab_len += vcol_off;
// boguscols before FIX_FOR_BOGUSCOLS macro from above // boguscols before FIX_FOR_BOGUSCOLS macro from above
if (wp->w_p_list && wp->w_lcs_chars.tab1 if (wp->w_p_list && wp->w_lcs_chars.tab1
&& old_boguscols > 0 && old_boguscols > 0
&& n_extra > tab_len) && n_extra > tab_len)
tab_len += n_extra - tab_len; tab_len += n_extra - tab_len;
#endif # endif
// If n_extra > 0, it gives the number of chars, to
// if n_extra > 0, it gives the number of chars, to
// use for a tab, else we need to calculate the width // use for a tab, else we need to calculate the width
// for a tab // for a tab.
len = (tab_len * mb_char2len(wp->w_lcs_chars.tab2)); len = (tab_len * mb_char2len(wp->w_lcs_chars.tab2));
if (wp->w_lcs_chars.tab3)
len += mb_char2len(wp->w_lcs_chars.tab3);
if (n_extra > 0) if (n_extra > 0)
len += n_extra - tab_len; len += n_extra - tab_len;
c = wp->w_lcs_chars.tab1; c = wp->w_lcs_chars.tab1;
p = alloc(len + 1); p = alloc(len + 1);
vim_memset(p, ' ', len); if (p == NULL)
p[len] = NUL; n_extra = 0;
vim_free(p_extra_free); else
p_extra_free = p;
for (i = 0; i < tab_len; i++)
{ {
int lcs = wp->w_lcs_chars.tab2; vim_memset(p, ' ', len);
p[len] = NUL;
if (*p == NUL) vim_free(p_extra_free);
p_extra_free = p;
for (i = 0; i < tab_len; i++)
{ {
tab_len = i; int lcs = wp->w_lcs_chars.tab2;
break;
}
// if tab3 is given, need to change the char if (*p == NUL)
// for tab {
if (wp->w_lcs_chars.tab3 && i == tab_len - 1) tab_len = i;
lcs = wp->w_lcs_chars.tab3; break;
mb_char2bytes(lcs, p); }
p += mb_char2len(lcs);
n_extra += mb_char2len(lcs) // if tab3 is given, use it for the last char
if (wp->w_lcs_chars.tab3 && i == tab_len - 1)
lcs = wp->w_lcs_chars.tab3;
p += mb_char2bytes(lcs, p);
n_extra += mb_char2len(lcs)
- (saved_nextra > 0 ? 1 : 0); - (saved_nextra > 0 ? 1 : 0);
}
p_extra = p_extra_free;
# ifdef FEAT_CONCEAL
// n_extra will be increased by FIX_FOX_BOGUSCOLS
// macro below, so need to adjust for that here
if (vcol_off > 0)
n_extra -= vcol_off;
# endif
} }
p_extra = p_extra_free;
#ifdef FEAT_CONCEAL
// n_extra will be increased by FIX_FOX_BOGUSCOLS
// macro below, so need to adjust for that here
if (vcol_off > 0)
n_extra -= vcol_off;
#endif
} }
#endif #endif
#ifdef FEAT_CONCEAL #ifdef FEAT_CONCEAL

View File

@@ -70,6 +70,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;")

View File

@@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
3410,
/**/ /**/
3409, 3409,
/**/ /**/