Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@ychin
Copy link
Contributor

@ychin ychin commented Jul 20, 2025

Fix an array out of bounds crash when using diffopt+=inline:char when 4 or more buffers are being diff'ed. This happens when one of the blocks is empty. The inline highlight logic skips using that buffer's block, but when another buffer is used later and calls diff_read() to merge the diff blocks together, it could erroneously consider the empty block's diff info which has not been initialized, leaving to diff numbers that are invalid. Later on the diff num is used without bounds checking which leads to the crash.

Fix this by making sure to unset tp_diffbuf to NULL when we skip a block, so diff_read() will not consider this buffer to be used within inline diff. Also, add more bounds checking just to be safe.

Edit: Original issue that added this crash: #16881.

Fix an array out of bounds crash when using diffopt+=inline:char when 4
or more buffers are being diff'ed. This happens when one of the blocks
is empty. The inline highlight logic skips using that buffer's block,
but when another buffer is used later and calls diff_read() to merge the
diff blocks together, it could erroneously consider the empty block's
diff info which has not been initialized, leaving to diff numbers that
are invalid. Later on the diff num is used without bounds checking which
leads to the crash.

Fix this by making sure to unset tp_diffbuf to NULL when we skip a
block, so diff_read() will not consider this buffer to be used within
inline diff. Also, add more bounds checking just to be safe.
@ychin
Copy link
Contributor Author

ychin commented Jul 20, 2025

Credit to Ilya Grigoriev for finding this issue.

@chrisbra
Copy link
Member

thanks

@chrisbra chrisbra closed this in c8b99e2 Jul 20, 2025
@ychin ychin deleted the diff-inline-char-multibuffer-crash-fix branch July 20, 2025 07:24
@ychin
Copy link
Contributor Author

ychin commented Jul 20, 2025

@zeertzjq Probably should merge this to Neovim to address a crash in inline highlight.

zeertzjq added a commit to zeertzjq/neovim that referenced this pull request Jul 20, 2025
Problem:  Crash when using inline diff mode
          (Ilya Grigoriev)
Solution: Set tp_diffbuf to NULL when skipping a diff block
          (Yee Cheng Chin).

Fix an array out of bounds crash when using diffopt+=inline:char when 4
or more buffers are being diff'ed. This happens when one of the blocks
is empty. The inline highlight logic skips using that buffer's block,
but when another buffer is used later and calls diff_read() to merge the
diff blocks together, it could erroneously consider the empty block's
diff info which has not been initialized, leaving to diff numbers that
are invalid. Later on the diff num is used without bounds checking which
leads to the crash.

Fix this by making sure to unset tp_diffbuf to NULL when we skip a
block, so diff_read() will not consider this buffer to be used within
inline diff. Also, add more bounds checking just to be safe.

closes: vim/vim#17805

vim/vim@c8b99e2

Co-authored-by: Yee Cheng Chin <[email protected]>
zeertzjq added a commit to neovim/neovim that referenced this pull request Jul 20, 2025
Problem:  Crash when using inline diff mode
          (Ilya Grigoriev)
Solution: Set tp_diffbuf to NULL when skipping a diff block
          (Yee Cheng Chin).

Fix an array out of bounds crash when using diffopt+=inline:char when 4
or more buffers are being diff'ed. This happens when one of the blocks
is empty. The inline highlight logic skips using that buffer's block,
but when another buffer is used later and calls diff_read() to merge the
diff blocks together, it could erroneously consider the empty block's
diff info which has not been initialized, leaving to diff numbers that
are invalid. Later on the diff num is used without bounds checking which
leads to the crash.

Fix this by making sure to unset tp_diffbuf to NULL when we skip a
block, so diff_read() will not consider this buffer to be used within
inline diff. Also, add more bounds checking just to be safe.

closes: vim/vim#17805

vim/vim@c8b99e2

Co-authored-by: Yee Cheng Chin <[email protected]>
AungMyoKyaw pushed a commit to AungMyoKyaw/neovim that referenced this pull request Jul 20, 2025
Problem:  Crash when using inline diff mode
          (Ilya Grigoriev)
Solution: Set tp_diffbuf to NULL when skipping a diff block
          (Yee Cheng Chin).

Fix an array out of bounds crash when using diffopt+=inline:char when 4
or more buffers are being diff'ed. This happens when one of the blocks
is empty. The inline highlight logic skips using that buffer's block,
but when another buffer is used later and calls diff_read() to merge the
diff blocks together, it could erroneously consider the empty block's
diff info which has not been initialized, leaving to diff numbers that
are invalid. Later on the diff num is used without bounds checking which
leads to the crash.

Fix this by making sure to unset tp_diffbuf to NULL when we skip a
block, so diff_read() will not consider this buffer to be used within
inline diff. Also, add more bounds checking just to be safe.

closes: vim/vim#17805

vim/vim@c8b99e2

Co-authored-by: Yee Cheng Chin <[email protected]>
@ilyagr
Copy link
Contributor

ilyagr commented Jul 21, 2025

Thank you very much for fixing it!

dundargoc pushed a commit to dundargoc/neovim that referenced this pull request Sep 27, 2025
Problem:  Crash when using inline diff mode
          (Ilya Grigoriev)
Solution: Set tp_diffbuf to NULL when skipping a diff block
          (Yee Cheng Chin).

Fix an array out of bounds crash when using diffopt+=inline:char when 4
or more buffers are being diff'ed. This happens when one of the blocks
is empty. The inline highlight logic skips using that buffer's block,
but when another buffer is used later and calls diff_read() to merge the
diff blocks together, it could erroneously consider the empty block's
diff info which has not been initialized, leaving to diff numbers that
are invalid. Later on the diff num is used without bounds checking which
leads to the crash.

Fix this by making sure to unset tp_diffbuf to NULL when we skip a
block, so diff_read() will not consider this buffer to be used within
inline diff. Also, add more bounds checking just to be safe.

closes: vim/vim#17805

vim/vim@c8b99e2

Co-authored-by: Yee Cheng Chin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants