aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-07-05 16:30:23 +0800
committerGitHub <noreply@github.com>2023-07-05 16:30:23 +0800
commit317038e7cb11d3db3f3b4679e260de4e119c210c (patch)
tree44b6819a5816825b69f171d575db062c2322e4d8
parent5936a88f181e52e17484d4ae6dfaea7d50d43935 (diff)
downloadrneovim-317038e7cb11d3db3f3b4679e260de4e119c210c.tar.gz
rneovim-317038e7cb11d3db3f3b4679e260de4e119c210c.tar.bz2
rneovim-317038e7cb11d3db3f3b4679e260de4e119c210c.zip
fix(plines): don't return very large height on very long line (#24260)
-rw-r--r--src/nvim/plines.c22
-rw-r--r--test/functional/legacy/scroll_opt_spec.lua40
2 files changed, 49 insertions, 13 deletions
diff --git a/src/nvim/plines.c b/src/nvim/plines.c
index 46bbbeeb07..615ce9100b 100644
--- a/src/nvim/plines.c
+++ b/src/nvim/plines.c
@@ -98,19 +98,15 @@ int plines_win_nofill(win_T *wp, linenr_T lnum, bool winheight)
/// "wp". Does not care about folding, 'wrap' or 'diff'.
int plines_win_nofold(win_T *wp, linenr_T lnum)
{
- char *s;
- unsigned col;
- int width;
+ char *s = ml_get_buf(wp->w_buffer, lnum, false);
chartabsize_T cts;
-
- s = ml_get_buf(wp->w_buffer, lnum, false);
init_chartabsize_arg(&cts, wp, lnum, 0, s, s);
if (*s == NUL && !cts.cts_has_virt_text) {
return 1; // be quick for an empty line
}
win_linetabsize_cts(&cts, (colnr_T)MAXCOL);
clear_chartabsize_arg(&cts);
- col = (unsigned)cts.cts_vcol;
+ int64_t col = cts.cts_vcol;
// If list mode is on, then the '$' at the end of the line may take up one
// extra column.
@@ -119,17 +115,17 @@ int plines_win_nofold(win_T *wp, linenr_T lnum)
}
// Add column offset for 'number', 'relativenumber' and 'foldcolumn'.
- width = wp->w_width_inner - win_col_off(wp);
- if (width <= 0 || col > 32000) {
- return 32000; // bigger than the number of screen columns
+ int width = wp->w_width_inner - win_col_off(wp);
+ if (width <= 0) {
+ return 32000; // bigger than the number of screen lines
}
- if (col <= (unsigned)width) {
+ if (col <= width) {
return 1;
}
- col -= (unsigned)width;
+ col -= width;
width += win_col_off2(wp);
- assert(col <= INT_MAX && (int)col < INT_MAX - (width - 1));
- return ((int)col + (width - 1)) / width + 1;
+ const int64_t lines = (col + (width - 1)) / width + 1;
+ return (lines > 0 && lines <= INT_MAX) ? (int)lines : INT_MAX;
}
/// Like plines_win(), but only reports the number of physical screen lines
diff --git a/test/functional/legacy/scroll_opt_spec.lua b/test/functional/legacy/scroll_opt_spec.lua
index ae6a409762..b179338665 100644
--- a/test/functional/legacy/scroll_opt_spec.lua
+++ b/test/functional/legacy/scroll_opt_spec.lua
@@ -1109,4 +1109,44 @@ describe('smoothscroll', function()
|
]])
end)
+
+ it('works with very long line', function()
+ screen:set_default_attr_ids({
+ [1] = {foreground = Screen.colors.Brown},
+ [2] = {foreground = Screen.colors.Blue1, bold = true},
+ })
+ exec([[
+ edit test/functional/fixtures/bigfile_oneline.txt
+ setlocal smoothscroll number
+ ]])
+ screen:expect([[
+ {1: 1 }^0000;<control>;Cc;0;BN;;;;;N;NULL;;;|
+ {1: }; 0001;<control>;Cc;0;BN;;;;;N;START|
+ {1: } OF HEADING;;;; 0002;<control>;Cc;0;|
+ {1: }BN;;;;;N;START OF TEXT;;;; 0003;<con|
+ {1: }trol>;Cc;0;BN;;;;;N;END OF TEXT;;;; |
+ {1: }0004;<control>;Cc;0;BN;;;;;N;END OF |
+ {1: }TRANSMISSION;;;; 0005;<control>;Cc;0|
+ {1: };BN;;;;;N;ENQUIRY;;;; 0006;<control>|
+ {1: };Cc;0;BN;;;;;N;ACKNOWLEDGE;;;; 0007;|
+ {1: }<control>;Cc;0;BN;;;;;N;BELL;;;; 000|
+ {1: }8;<control>;Cc;0;BN;;;;;N;BACKSPACE;|
+ |
+ ]])
+ feed('j')
+ screen:expect([[
+ {2:<<<}{1: }CJK COMPATIBILITY IDEOGRAPH-2F91F;Lo|
+ {1: };0;L;243AB;;;;N;;;;; 2F920;CJK COMPA|
+ {1: }TIBILITY IDEOGRAPH-2F920;Lo;0;L;7228|
+ {1: };;;;N;;;;; 2F921;CJK COMPATIBILITY I|
+ {1: }DEOGRAPH-2F921;Lo;0;L;7235;;;;N;;;;;|
+ {1: } 2F922;CJK COMPATIBILITY IDEOGRAPH-2|
+ {1: }F922;Lo;0;L;7250;;;;N;;;;; |
+ {1: 2 }^2F923;CJK COMPATIBILITY IDEOGRAPH-2F|
+ {1: }923;Lo;0;L;24608;;;;N;;;;; |
+ {1: 3 }2F924;CJK COMPATIBILITY IDEOGRAPH-2F|
+ {1: }924;Lo;0;L;7280;;;;N;;;;; |
+ |
+ ]])
+ end)
end)