diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-07-05 16:30:23 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-05 16:30:23 +0800 |
commit | 317038e7cb11d3db3f3b4679e260de4e119c210c (patch) | |
tree | 44b6819a5816825b69f171d575db062c2322e4d8 | |
parent | 5936a88f181e52e17484d4ae6dfaea7d50d43935 (diff) | |
download | rneovim-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.c | 22 | ||||
-rw-r--r-- | test/functional/legacy/scroll_opt_spec.lua | 40 |
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) |