Josh Rickmar discovered a bug in 'got cherrypick' where an error
was raised even though the merge should have succeeded: 
        got: unexpected end of file

I have traced this back into OpenBSD's diff3(1) implementation.

With the 3 attached files called a, b, and c (files a and b lack the
trailing newline), I see the following:

$ diff3 /tmp/{a,b,c} 
====
1:3c
  aaa
2:3c
  bbb
3:3c
  ccc
diff3prog: logic error
$ 

$ merge -p /tmp/{a,b,c}
merge: failed to merge
$ 

The problem is that the code scanning a common chunk of lines doesn't
account for the possibility that EOF may occur before a final newline.

This patch fixes the problem in all affected tools in the tree. OK?

diff 65b1cd8393dafa03a122f9d52069f5dae4940079 /usr/src
blob - f0fee1c19257e3bfee226f5d14499ccfe51aef2f
file + usr.bin/cvs/diff3.c
--- usr.bin/cvs/diff3.c
+++ usr.bin/cvs/diff3.c
@@ -743,6 +743,8 @@ duplicate(struct range *r1, struct range *r2)
                do {
                        c = getc(fp[0]);
                        d = getc(fp[1]);
+                       if (c == -1 && d == -1)
+                               break;
                        if (c == -1 || d== -1)
                                return (-1);
                        nchar++;
blob - a56bfc7ce7aa7b4edf04599ce3805201eaf9911d
file + usr.bin/diff3/diff3prog.c
--- usr.bin/diff3/diff3prog.c
+++ usr.bin/diff3/diff3prog.c
@@ -494,6 +494,8 @@ duplicate(struct range *r1, struct range *r2)
                do {
                        c = getc(fp[0]);
                        d = getc(fp[1]);
+                       if (c == -1 && d == -1)
+                               break;
                        if (c == -1 || d== -1)
                                trouble();
                        nchar++;
blob - ebe04a3b70556f126666dc1431e90842536462d6
file + usr.bin/rcs/diff3.c
--- usr.bin/rcs/diff3.c
+++ usr.bin/rcs/diff3.c
@@ -838,6 +838,8 @@ duplicate(struct range *r1, struct range *r2)
                do {
                        c = getc(fp[0]);
                        d = getc(fp[1]);
+                       if (c == -1 && d == -1)
+                               break;
                        if (c == -1 || d== -1)
                                return (-1);
                        nchar++;
aaa
aaa
aaa
aaa
aaa
aaa
aaa
aaa
bbb
aaa
aaa
aaa
aaa
aaa
ccc
aaa
aaa
aaa

Reply via email to