NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/46158: find(1) lies



>Number:         46158
>Category:       bin
>Synopsis:       find(1) lies
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          doc-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Mar 09 12:35:00 +0000 2012
>Originator:     Robert Elz
>Release:        NetBSD 2 -> current (everything for the past 9.5 years)
>Organization:
        Prince of Songkla University
>Environment:
System: NetBSD jade.coe.psu.ac.th 5.1_STABLE NetBSD 5.1_STABLE 
(JADE-1.12-20120130) #27: Tue Jan 31 05:20:31 ICT 2012 
kre%jade.coe.psu.ac.th@localhost:/usr/obj/5/kernels/i386/JADE i386
Architecture: i386
Machine: i386
>Description:
        This is non-critical/low because this problem has been around
        for almost 10 years now, and doesn't seem to bother anyone
        too much.   Yet:

        find(1) claims ...

     All primaries which take a numeric argument of n allow the number to be
     preceded by a plus sign (``+'') or a minus sign (``-'').  A preceding
     plus sign means ``more than n'', a preceding minus sign means ``less than
     n'', and neither means ``exactly n''.

        Note in particular the "All".

        Then consider the 2 primaries ...

     -maxdepth n
             True if the current search depth is less than or equal to what is
             specified in n.

     -mindepth n
             True if the current search depth is at least what is specified in
             n.

        In neither of those is the numeric argument treated the way
        that the man page promised will be used for "All primaries that
        take a numeric argument" yet they take a numeric argument, and
        even use find(1)'s 'n' arg notation to indicate that.

        I know those two were added (in Sept 2002 - which is why the 9.5
        years of lies) the way they were to be compatible with other versions
        of find - pity that - we really should not allow other people's
        mistakes to cause us to make similar mistakes.   The right way to
        allow the functionality would have been to add a single primitive
        (-depth would have been nice had it not already been used elsewhere)
        that tests the numeric parameter the same way all other numeric
        parameters are tested.

        While I am here, I also see that -user, which doesn't strictly
        take a numeric argument, but which does allow a numeric value instead
        of the "uname" does (correctly, more or less) allow the +n n & -n
        forms (and is documented to do so), but -group does not, yet its arg
        is documented as being able to be numeric (the doc doesn't have the
        extra comment that the -user section includes about what that means
        however).

>How-To-Repeat:
        RTFM, UTSL ...

        For the "more or less" comment in the last paragraph of the
        Description section of this PR, consider

                find / -user 0c
        compared with
                find / -user +0c

        Both fail (assuming your system doesn't have users with either of
        those user names of course), but they fail in different ways, caused
        by the somewhat bizarre way the arg is tested to see if it is
        numeric.   Parsing the args to find is not where find spends its
        time .. we could afford a few extra nanoseconds to do it properly.

>Fix:
        Fixing the doc would be as simple as s/All/Most/ - but that would be
        a disgusting fix, and lead to a man page that means almost nothing.

        Better would be to discard the -mxxdepth primitives and replace them
        with something rational.  If not completely discarded (because of
        compat reasons) they could at least be augmented by a sane primitive
        and relegated to being documented as a a couple of very weird non
        standard special cases.

        -group should get processing added similar to what was done for -user.
        Perhaps both of those could benefit from using a function like:

bool
numstring(char *str)
{
        char *p;
        char c;

        c = *str;
        if (c == '+' || c == '-')
                str++;

        for (p = str; c = *p++; )
                if (!isdigit(c))
                        return false;

        return (p > str);
}

        rather than screwing around with testing whether atoi() returns 0
        (and then trying to handle the special cases) to determine if the
        arg really is numeric or not (for all I know there might already be
        a libc function that does this) to avoid getting errors from
        find_parsenum() so we can have a consistent "no such user" (or
        group) error message for all bogus args to -user (and -group).



Home | Main Index | Thread Index | Old Index