diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-01-21 18:16:16 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-01-21 18:16:16 +0800 |
commit | cb39c825c49c5557f8df5a1242907c49cacad4b1 (patch) | |
tree | be05b830086e9cc2eef5980687d120abd5f43f0d /src/nvim/screen.c | |
parent | 296b8fbe3b62984210bb93c7d64b68cd1dd479b7 (diff) | |
download | rneovim-cb39c825c49c5557f8df5a1242907c49cacad4b1.tar.gz rneovim-cb39c825c49c5557f8df5a1242907c49cacad4b1.tar.bz2 rneovim-cb39c825c49c5557f8df5a1242907c49cacad4b1.zip |
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)
https://github.com/vim/vim/commit/89a54b413a8c96206ce7e038dde81a6eff6cd6b8
Diffstat (limited to 'src/nvim/screen.c')
-rw-r--r-- | src/nvim/screen.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/src/nvim/screen.c b/src/nvim/screen.c index ab726dfdb0..6a8792b7b6 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -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; } - // 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 - // for a tab + // for a tab. 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) { len += n_extra - tab_len; } c = wp->w_p_lcs_chars.tab1; p = xmalloc(len + 1); - memset(p, ' ', len); - p[len] = NUL; - xfree(p_extra_free); - p_extra_free = p; - for (i = 0; i < tab_len; i++) { - if (*p == NUL) { - tab_len = i; - break; - } - int lcs = wp->w_p_lcs_chars.tab2; + if (p == NULL) { + n_extra = 0; + } else { + memset(p, ' ', len); + p[len] = NUL; + xfree(p_extra_free); + p_extra_free = p; + for (i = 0; i < tab_len; i++) { + if (*p == NUL) { + tab_len = i; + break; + } + int lcs = wp->w_p_lcs_chars.tab2; - // if tab3 is given, need to change the char - // for tab - if (wp->w_p_lcs_chars.tab3 && i == tab_len - 1) { - lcs = wp->w_p_lcs_chars.tab3; + // if tab3 is given, use it for the last char + if (wp->w_p_lcs_chars.tab3 && i == tab_len - 1) { + 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 += utf_char2len(lcs); - n_extra += utf_char2len(lcs) - (saved_nextra > 0 ? 1 : 0); - } - p_extra = p_extra_free; + p_extra = p_extra_free; - // 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; + // 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; + } } } |