Subject: bin/6412: find(1) logic broken
To: None <gnats-bugs@gnats.netbsd.org>
From: None <dave@dtsp.co.nz>
List: netbsd-bugs
Date: 11/09/1998 10:35:05
>Number:         6412
>Category:       bin
>Synopsis:       find(1) logic broken
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Nov  9 03:05:01 1998
>Last-Modified:
>Originator:     Dave Sainty
>Organization:
Dynamic Technology Services and Products Ltd (NZ)
>Release:        sup 9/11/98 (19981109)
>Environment:
System: NetBSD tequila.dave.dtsp.co.nz 1.3G NetBSD 1.3G (TEQUILA) #1: Thu Aug 20 00:13:30 NZST 1998 dave@tequila.dave.dtsp.co.nz:/vol/tequila/userC/NetBSD-current/src/sys/arch/i386/compile/TEQUILA i386


>Description:
	find logic appears to be broken
>How-To-Repeat:

tequila [/tmp] % mkdir /tmp/x
tequila [/tmp] % cd /tmp/x
tequila [/tmp/x] % touch new
tequila [/tmp/x] % find . -mtime -1 -a -ls
 384866      2 drwx------    2 dave     wheel          512 Nov  9 19:42 .
 384867      0 -rw-------    1 dave     wheel            0 Nov  9 19:42 ./new
tequila [/tmp/x] % find . \( \! -mtime -1 \) -a -ls
tequila [/tmp/x] % find . \! \( \! -mtime -1 \) -a -ls
tequila [/tmp/x] % find . \( \! \( \! -mtime -1 \) \) -a -ls

The last two should output the files, but don't.

Next is correct...

tequila [/tmp/x] % find . \! \! -mtime -1 -a -ls
 384866      2 drwx------    2 dave     wheel          512 Nov  9 19:42 .
 384867      0 -rw-------    1 dave     wheel            0 Nov  9 19:42 ./new

Correct

tequila [/tmp/x] % find . \! -mtime -1 -a -ls

Incorrect

tequila [/tmp/x] % find . \! \( \! -mtime -1 \) -a -ls

Correct

tequila [/tmp/x] % find . \! \! \( -mtime -1 \) -a -ls
 384866      2 drwx------    2 dave     wheel          512 Nov  9 19:42 .
 384867      0 -rw-------    1 dave     wheel            0 Nov  9 19:42 ./new

Correct

tequila [/tmp/x] % find . \( \! \! \( -mtime -1 \) \) -a -ls
 384866      2 drwx------    2 dave     wheel          512 Nov  9 19:42 .
 384867      0 -rw-------    1 dave     wheel            0 Nov  9 19:42 ./new

Correct

tequila [/tmp/x] % find . \( \! \! -mtime -1 \) -a -ls
 384866      2 drwx------    2 dave     wheel          512 Nov  9 19:42 .
 384867      0 -rw-------    1 dave     wheel            0 Nov  9 19:42 ./new

A few more tests convinced me it's a problem with inverting the result of
parenthesised expressions.

Incorrect :)

tequila [/tmp/x] % find . \!
zsh: 22332 segmentation fault (core dumped)  find . !

>Fix:

The first hunk fixes the core, the second fixes the original problem.  To
explain, find(1) generates a parse tree and then does several passes over it.
This function is called during the ! pass, during which it converts 'NOT x'
into 'NOT(x)'.  However, if the parameter to a ! is a complex expression, it
was not recursed and remained in the tree as two following nodes, 'NOT x'.
This is interpreted as 'NOT(NULL) AND x'.  Not quite the intention :)

--- src/usr.bin/find/operator.c.orig    Mon Nov  9 23:16:30 1998
+++ src/usr.bin/find/operator.c Mon Nov  9 23:14:45 1998
@@ -199,7 +199,7 @@
                        int notlevel = 1;
 
                        node = yanknode(&plan);
-                       while (node->type == N_NOT) {
+                       while (node != NULL && node->type == N_NOT) {
                                ++notlevel;
                                node = yanknode(&plan);
                        }
@@ -207,6 +207,9 @@
                                errx(1, "!: no following expression");
                        if (node->type == N_OR)
                                errx(1, "!: nothing between ! and -o");
+                       /* look for nots in the parameter */
+                       if (node->type == N_EXPR)
+                               node = not_squish(node);
                        if (notlevel % 2 != 1)
                                next = node;
                        else
>Audit-Trail:
>Unformatted: