Bug 252614

Summary: /usr/bin/diff : BUG: Incorrectly displaying files as duplicates (includes fix)
Product: Base System Reporter: Jamie Landeg-Jones <jamie>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Some People CC: bapt, jamie, kevans, lwhsu
Priority: ---    
Version: CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
patch to fix diff bug none

Description Jamie Landeg-Jones 2021-01-12 16:53:19 UTC
Created attachment 221499 [details]
patch to fix diff bug

When diff hits certain access errors, function diffreg() shows the error message, and then returns to the calling function, which calls print_status() with the return value.

However, in these cases, the return value isn't changed from the initial default value of D_SAME.

Normally, print_status() with a value of D_SAME does nothing, so this works out ok, however, if the "-s" flag is set, a message is displayed showing identicality:

case D_SAME:
                if (sflag)
                        printf("Files %s%s and %s%s are identical\n",                                                                                                       path1, entry, path2, entry);
                break;

This then produces such results as:

% diff  -s /COPYRIGHT /var/run/rpcbind.sock
diff: /var/run/rpcbind.sock: Operation not supported
Files /COPYRIGHT and /var/run/rpcbind.sock are identical

% diff  -s /COPYRIGHT /etc/master.passwd
diff: /etc/master.passwd: Permission denied
Files /COPYRIGHT and /etc/master.passwd are identical

A quick fix would be to alter the above line:

   if (sflag)

to

   if (sflag && status & 2)

A less hacky fix is attached as a patch. It creates a D_ERROR status which is returned in such cases, and print_status() then deals with that status seperately from D_SAME.
Comment 1 John Baldwin freebsd_committer freebsd_triage 2021-01-15 23:44:11 UTC
Adding bapt@ and kevans@ in case they want to look as they've hacked on diff(1) recently.
Comment 2 commit-hook freebsd_committer freebsd_triage 2021-01-25 19:39:31 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=fefb3c46a80fdde6f307e73a2b5b5aed806df1ce

commit fefb3c46a80fdde6f307e73a2b5b5aed806df1ce
Author:     Jamie Landeg-Jones <jamie@catflap.org>
AuthorDate: 2021-01-25 17:42:26 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2021-01-25 19:38:18 +0000

    diff: fix incorrectly displaying files as duplicates

    When diff hits certain access errors, function diffreg() shows the error
    message, and then returns to the calling function, which calls
    print_status() with the return value.

    However, in these cases, the return value isn't changed from the initial
    default value of D_SAME.

    Normally, print_status() with a value of D_SAME does nothing, so this
    works out ok, however, if the "-s" flag is set, a message is displayed
    showing identicality:

    case D_SAME:
                    if (sflag)
                            printf("Files %s%s and %s%s are identical\n",                                                                                                       path1, entry, path2, entry);
                    break;

    This then produces such results as:

    % diff  -s /COPYRIGHT /var/run/rpcbind.sock
    diff: /var/run/rpcbind.sock: Operation not supported
    Files /COPYRIGHT and /var/run/rpcbind.sock are identical

    % diff  -s /COPYRIGHT /etc/master.passwd
    diff: /etc/master.passwd: Permission denied
    Files /COPYRIGHT and /etc/master.passwd are identical

    Create a D_ERROR status which is returned in such cases, and
    print_status() then deals with that status seperately from D_SAME

    PR:             252614
    MFC after:      1 week

 usr.bin/diff/diff.c    | 2 ++
 usr.bin/diff/diff.h    | 1 +
 usr.bin/diff/diffreg.c | 5 +++++
 3 files changed, 8 insertions(+)
Comment 3 Baptiste Daroussin freebsd_committer freebsd_triage 2021-01-25 19:39:57 UTC
thank you, fixed, I will merge this next week to ensure we have it in freebsd 13.0
Comment 4 commit-hook freebsd_committer freebsd_triage 2021-02-01 13:06:31 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=3728c4d3149553967532a97254737bdb2cd92417

commit 3728c4d3149553967532a97254737bdb2cd92417
Author:     Jamie Landeg-Jones <jamie@catflap.org>
AuthorDate: 2021-01-25 17:42:26 +0000
Commit:     Baptiste Daroussin <bapt@FreeBSD.org>
CommitDate: 2021-02-01 13:05:25 +0000

    diff: fix incorrectly displaying files as duplicates

    When diff hits certain access errors, function diffreg() shows the error
    message, and then returns to the calling function, which calls
    print_status() with the return value.

    However, in these cases, the return value isn't changed from the initial
    default value of D_SAME.

    Normally, print_status() with a value of D_SAME does nothing, so this
    works out ok, however, if the "-s" flag is set, a message is displayed
    showing identicality:

    case D_SAME:
                    if (sflag)
                            printf("Files %s%s and %s%s are identical\n",                                                                                                       path1, entry, path2, entry);
                    break;

    This then produces such results as:

    % diff  -s /COPYRIGHT /var/run/rpcbind.sock
    diff: /var/run/rpcbind.sock: Operation not supported
    Files /COPYRIGHT and /var/run/rpcbind.sock are identical

    % diff  -s /COPYRIGHT /etc/master.passwd
    diff: /etc/master.passwd: Permission denied
    Files /COPYRIGHT and /etc/master.passwd are identical

    Create a D_ERROR status which is returned in such cases, and
    print_status() then deals with that status seperately from D_SAME

    PR:             252614
    MFC after:      1 week

    (cherry picked from commit fefb3c46a80fdde6f307e73a2b5b5aed806df1ce)

 usr.bin/diff/diff.c    | 2 ++
 usr.bin/diff/diff.h    | 1 +
 usr.bin/diff/diffreg.c | 5 +++++
 3 files changed, 8 insertions(+)
Comment 5 Jamie Landeg-Jones 2021-02-01 19:08:14 UTC
(In reply to commit-hook from comment #4)

Thanks Baptiste!