# HG changeset patch # User Bram Moolenaar # Date 1640717104 -3600 # Node ID 83a99f08d1e874ffb4d6a693a134d347743a552e # Parent 94487b9fdd2a0196c13a9e3fc5deecff24cee15a patch 8.2.3925: diff mode confused by NUL bytes Commit: https://github.com/vim/vim/commit/06f6095623cfcc72da08748c058d13b465652fd4 Author: Bram Moolenaar Date: Tue Dec 28 18:30:05 2021 +0000 patch 8.2.3925: diff mode confused by NUL bytes Problem: Diff mode confused by NUL bytes. Solution: Handle NUL bytes differently. (Christian Brabandt, closes https://github.com/vim/vim/issues/9421, closes #9418) diff --git a/src/diff.c b/src/diff.c --- a/src/diff.c +++ b/src/diff.c @@ -777,9 +777,14 @@ diff_write_buffer(buf_T *buf, diffin_T * int orig_len; char_u cbuf[MB_MAXBYTES + 1]; - // xdiff doesn't support ignoring case, fold-case the text. - c = PTR2CHAR(s); - c = MB_CASEFOLD(c); + if (*s == NL) + c = NUL; + else + { + // xdiff doesn't support ignoring case, fold-case the text. + c = PTR2CHAR(s); + c = MB_CASEFOLD(c); + } orig_len = mb_ptr2len(s); if (mb_char2bytes(c, cbuf) != orig_len) // TODO: handle byte length difference @@ -791,7 +796,10 @@ diff_write_buffer(buf_T *buf, diffin_T * len += orig_len; } else - ptr[len++] = *s++; + { + ptr[len++] = *s == NL ? NUL : *s; + s++; + } } ptr[len++] = NL; } diff --git a/src/testdir/dumps/Test_diff_bin_01.dump b/src/testdir/dumps/Test_diff_bin_01.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_diff_bin_01.dump @@ -0,0 +1,20 @@ +| +0#0000e05#a8a8a8255@1>A+2#0000000#ff404010| +0&#ffd7ff255@33||+1&#ffffff0| +0#0000e05#a8a8a8255@1|a+2#0000000#ff404010| +0&#ffd7ff255@33 +| +0#0000e05#a8a8a8255@1|b+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|b+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|c+0#0000000#ffd7ff255| @33||+1&#ffffff0| +0#0000e05#a8a8a8255@1|c+0#0000000#ffd7ff255|^+2#0000e05#ff404010|@| +0#0000000#ffd7ff255@31 +| +0#0000e05#a8a8a8255@1|d+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|d+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|E+2#0000000#ff404010| +0&#ffd7ff255@33||+1&#ffffff0| +0#0000e05#a8a8a8255@1|e+2#0000000#ff404010| +0&#ffd7ff255@33 +| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|g+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|g+0#0000000#ffffff0| @33 +|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 +| +0&&@74 diff --git a/src/testdir/dumps/Test_diff_bin_02.dump b/src/testdir/dumps/Test_diff_bin_02.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_diff_bin_02.dump @@ -0,0 +1,20 @@ +| +0#0000e05#a8a8a8255@1>A+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|b+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|b+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|c+0#0000000#ffd7ff255| @33||+1&#ffffff0| +0#0000e05#a8a8a8255@1|c+0#0000000#ffd7ff255|^+2#0000e05#ff404010|@| +0#0000000#ffd7ff255@31 +| +0#0000e05#a8a8a8255@1|d+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|d+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|E+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|e+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|g+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|g+0#0000000#ffffff0| @33 +|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 +| +0&&@74 diff --git a/src/testdir/dumps/Test_diff_bin_03.dump b/src/testdir/dumps/Test_diff_bin_03.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_diff_bin_03.dump @@ -0,0 +1,20 @@ +| +0#0000e05#a8a8a8255@1>A+2#0000000#ff404010| +0&#ffd7ff255@33||+1&#ffffff0| +0#0000e05#a8a8a8255@1|a+2#0000000#ff404010| +0&#ffd7ff255@33 +| +0#0000e05#a8a8a8255@1|b+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|b+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|c+0#0000000#ffd7ff255| @33||+1&#ffffff0| +0#0000e05#a8a8a8255@1|c+0#0000000#ffd7ff255|^+2#0000e05#ff404010|@| +0#0000000#ffd7ff255@31 +| +0#0000e05#a8a8a8255@1|d+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|d+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|E+2#0000000#ff404010| +0&#ffd7ff255@33||+1&#ffffff0| +0#0000e05#a8a8a8255@1|e+2#0000000#ff404010| +0&#ffd7ff255@33 +| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|g+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|g+0#0000000#ffffff0| @33 +|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 +| +0&&@74 diff --git a/src/testdir/dumps/Test_diff_bin_04.dump b/src/testdir/dumps/Test_diff_bin_04.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_diff_bin_04.dump @@ -0,0 +1,20 @@ +| +0#0000e05#a8a8a8255@1>A+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|b+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|b+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|c+0#0000000#ffd7ff255| @33||+1&#ffffff0| +0#0000e05#a8a8a8255@1|c+0#0000000#ffd7ff255|^+2#0000e05#ff404010|@| +0#0000000#ffd7ff255@31 +| +0#0000e05#a8a8a8255@1|d+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|d+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|E+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|e+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|f+0#0000000#ffffff0| @33 +| +0#0000e05#a8a8a8255@1|g+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|g+0#0000000#ffffff0| @33 +|~+0#4040ff13&| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|~| @35||+1#0000000&|~+0#4040ff13&| @35 +|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1| |[+1&&|N|o| |N|a|m|e|]| |[|+|]| @5|1|,|1| @11|A|l@1 +| +0&&@74 diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim --- a/src/testdir/test_diffmode.vim +++ b/src/testdir/test_diffmode.vim @@ -1417,4 +1417,41 @@ func Test_diff_modify_chunks() %bw! endfunc +func Test_diff_binary() + CheckScreendump + + let content =<< trim END + call setline(1, ['a', 'b', "c\n", 'd', 'e', 'f', 'g']) + vnew + call setline(1, ['A', 'b', 'c', 'd', 'E', 'f', 'g']) + windo diffthis + wincmd p + norm! gg0 + redraw! + END + call writefile(content, 'Xtest_diff_bin') + let buf = RunVimInTerminal('-S Xtest_diff_bin', {}) + + " Test using internal diff + call VerifyScreenDump(buf, 'Test_diff_bin_01', {}) + + " Test using internal diff and case folding + call term_sendkeys(buf, ":set diffopt+=icase\") + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_diff_bin_02', {}) + " Test using external diff + call term_sendkeys(buf, ":set diffopt=filler\") + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_diff_bin_03', {}) + " Test using external diff and case folding + call term_sendkeys(buf, ":set diffopt=filler,icase\") + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_diff_bin_04', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('Xtest_diff_bin') + set diffopt&vim +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3925, +/**/ 3924, /**/ 3923,