*BSD News Article 85535


Return to BSD News archive

Path: euryale.cc.adfa.oz.au!newshost.carno.net.au!harbinger.cc.monash.edu.au!munnari.OZ.AU!news.ecn.uoknor.edu!news.wildstar.net!newsfeed.direct.ca!portc01.blue.aol.com!portc02.blue.aol.com!news.bbnplanet.com!cpk-news-hub1.bbnplanet.com!news.mindspring.com!tarush
From: tarush@mindspring.com (Tom Rush)
Newsgroups: comp.unix.bsd.freebsd.misc
Subject: /bin/test bug?
Date: 24 Dec 1996 04:49:19 GMT
Organization: Rush Co.
Lines: 43
Message-ID: <59nncf$m8c@camel0.mindspring.com>
NNTP-Posting-Host: user-168-121-119-56.dialup.mindspring.com
Xref: euryale.cc.adfa.oz.au comp.unix.bsd.freebsd.misc:33041

There appears to be a problem with /bin/test and the -a and -o
operators.

The problem occurs when using the form ' test "string" ', which
according to the man page, returns true if "string" is not a null
string.  If testing to see if a shell variable is unset or null, e.g.
' test "$VAR1" ', the shell passes a null string if VAR1 is unset, and
test returns 1, as expected.  However, if both VAR1 and VAR2 are unset,
the form ' test "$VAR1" -o "$VAR2" ' returns 0, not 1, as expected.
' test "$VAR1" -a "$VAR2" ' also returns 0.

The TEST.csh script in the source checks this (and fails); the TEST.sh
script in -current does not check for this.

In looking at the source, the problem is not hard to find.  The comments
in expr_operator() under case AND1 and OR1 say that "these operands are
mostly handled by the parser".  But in this situation, the expression is
never touched by the parser; it has been passed to posix_binary_op by
the special case code at the top of main().

The solution would appear to be to break out the "andor_op" case in the
main() code, so it will continue on to the parser (see patch).  This
same method is used just a few lines down from this point for a
different case.

This gives the results as described in the man page.
----------------
--- test.c.orig	Sat Dec 14 06:11:34 1996
+++ test.c	Mon Dec 23 22:47:13 1996
@@ -157,7 +157,7 @@
 			ret_val = posix_unary_op(&argv[1]);
 			if (ret_val >= 0)
 				return (!ret_val);
-		} else {
+		} else if (lookup_op(argv[2], andor_op) < 0) {
 			ret_val = posix_binary_op(&argv[1]);
 			if (ret_val >= 0)
 				return (ret_val);
----------------

-- 
Tom Rush
tarush@mindspring.com