From 0fca343d641c25f631a5125801d5cb3996e29f7c Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 4 Oct 2025 19:50:51 +0800 Subject: [PATCH] vim-patch:9.1.1823: diff: w_topline may be invalidated (#36018) Problem: diff: w_topline may be invalidated Solution: Update lnum in diff_set_topline() (Yee Cheng Chin). This can happen in ex_diffupdate() for certain edge cases which cause the logic to now be wrong. This was also the root cause for vim/vim#18437 where Vim would crash due to a null pointer dereferencing (said pointer would not be null under normal circumstances). related: vim/vim#18437 closes: vim/vim#18484 https://github.com/vim/vim/commit/dd9ed46a39df8a8b08ef4b491fdf53bcbfdc0c2d Co-authored-by: Yee Cheng Chin --- src/nvim/diff.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 1188b72821..c7efa66966 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -2052,7 +2052,9 @@ static void calculate_topfill_and_topline(const int fromidx, const int toidx, co // move the same amount of virtual lines in the target buffer to find the // cursor's line number - int curlinenum_to = thistopdiff != NULL ? thistopdiff->df_lnum[toidx] : 1; + int curlinenum_to + = thistopdiff != NULL // this should not be null, but just for safety + ? thistopdiff->df_lnum[toidx] : 1; int virt_lines_left = virtual_lines_passed; curdif = thistopdiff; @@ -2466,7 +2468,6 @@ static int diff_cmp(char *s1, char *s2) void diff_set_topline(win_T *fromwin, win_T *towin) { buf_T *frombuf = fromwin->w_buffer; - linenr_T lnum = fromwin->w_topline; int fromidx = diff_buf_idx(frombuf, curtab); if (fromidx == DB_COUNT) { @@ -2478,6 +2479,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin) // update after a big change ex_diffupdate(NULL); } + linenr_T lnum = fromwin->w_topline; towin->w_topfill = 0; // search for a change that includes "lnum" in the list of diffblocks.