Skip to content

Commit

Permalink
patch 8.2.3410: crash with linebreak, listchars and large tabstop
Browse files Browse the repository at this point in the history
Problem:    Crash with linebreak, listchars and large tabstop.
Solution:   Account for different size listchars for a tab. (closes #8841)
  • Loading branch information
brammool committed Sep 7, 2021
1 parent 65b6056 commit 89a54b4
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 31 deletions.
67 changes: 36 additions & 31 deletions src/drawline.c
Expand Up @@ -2109,55 +2109,60 @@ win_line(
int i;
int saved_nextra = n_extra;

#ifdef FEAT_CONCEAL
# ifdef FEAT_CONCEAL
if (vcol_off > 0)
// there are characters to conceal
tab_len += vcol_off;

// boguscols before FIX_FOR_BOGUSCOLS macro from above
if (wp->w_p_list && wp->w_lcs_chars.tab1
&& old_boguscols > 0
&& n_extra > tab_len)
tab_len += n_extra - tab_len;
#endif

// if n_extra > 0, it gives the number of chars, to
# endif
// If n_extra > 0, it gives the number of chars, to
// 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));
if (wp->w_lcs_chars.tab3)
len += mb_char2len(wp->w_lcs_chars.tab3);
if (n_extra > 0)
len += n_extra - tab_len;
c = wp->w_lcs_chars.tab1;
p = alloc(len + 1);
vim_memset(p, ' ', len);
p[len] = NUL;
vim_free(p_extra_free);
p_extra_free = p;
for (i = 0; i < tab_len; i++)
if (p == NULL)
n_extra = 0;
else
{
int lcs = wp->w_lcs_chars.tab2;

if (*p == NUL)
vim_memset(p, ' ', len);
p[len] = NUL;
vim_free(p_extra_free);
p_extra_free = p;
for (i = 0; i < tab_len; i++)
{
tab_len = i;
break;
}

// if tab3 is given, need to change the char
// for tab
if (wp->w_lcs_chars.tab3 && i == tab_len - 1)
lcs = wp->w_lcs_chars.tab3;
mb_char2bytes(lcs, p);
p += mb_char2len(lcs);
n_extra += mb_char2len(lcs)
int lcs = wp->w_lcs_chars.tab2;

if (*p == NUL)
{
tab_len = i;
break;
}

// 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);
}
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
#ifdef FEAT_CONCEAL
Expand Down
10 changes: 10 additions & 0 deletions src/testdir/test_listlbr_utf8.vim
Expand Up @@ -70,6 +70,16 @@ func Test_nolinebreak_with_list()
call s:close_windows()
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()
call s:test_windows('setl nolist')
call setline(1, "\t*mask = nil;")
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -755,6 +755,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3410,
/**/
3409,
/**/
Expand Down

0 comments on commit 89a54b4

Please sign in to comment.