expr(1) fails on negative arguments (with fix)

Dave Steffens das at cirl.UUCP
Mon Jun 9 11:47:05 AEST 1986


Subject: expr(1) fails on negative arguments (with fix)

Index: bin/expr.y

Description:
	expr(1) fails to handle negative arguments correctly.
	In particular, arithmetic operators will not accept
	negative arguments.  Additionally,  comparison operators
	use string comparison instead of arithmetic comparison
	if the second argument is negative.

	Additional fixes are included to eliminate the "illegal pointer
	integer combination" warnings from the 4.2bsd C compiler.

	I have cross-posted because these bugs exist in the v7 version
	and probably in various 2.9bsd and SYSV versions as well.

	CAVEAT: There may be a **good reason** why expr was **not**
	made to handle negative arguments.  The author of expr **did**
	include code to permit the first argument of comparison operators
	to be negative, presumably to handle the case where a sub-expression
	returned a negative result, e.g. expr 0 - 1 \< 0 and the like.
	Therefore, this posting may describe a fix which will **break
	something useful**.  If anyone knows of an example, PLEASE POST IT.

	Note to v7 (2.9bsd?) users:  While comparing v7 and 4.2bsd sources,
	I discovered that the 4.2bsd version contains additional bug fixes
	not present in the v7 source I have.  I presume these fixes shouldn't
	be divulged to those who don't have a 4.2bsd license so I haven't
	included them in my net.bugs.v7 posting.  Anyone care to comment?

Repeat-By:
	Arithmetic operator fails to handle a negative argument:
		expr 0 + -1
		non-numeric argument

	String comparison instead of arithmetic comparison:
		expr -2 \> -1
		1
	** because "-2" is lexicographically greater than "-1" **

Fix:
	In the following fixes, the line numbers shown refer to
	the 4.2bsd source for expr.y whose sccsid is
	"@(#)expr.y	4.3 (Berkeley) 6/30/83".

***** To fix the arithmetic operators:
116c123
< 	if(!(ematch(r1, "[0-9]*$") && ematch(r2, "[0-9]*$")))
---
> 	if(!(ematch(r1, "-*[0-9]*$") && ematch(r2, "-*[0-9]*$")))

***** To fix the comparison operators:
97c104
< 	if(ematch(r1, "-*[0-9]*$") && ematch(r2, "[0-9]*$"))
---
> 	if(ematch(r1, "-*[0-9]*$") && ematch(r2, "-*[0-9]*$"))

***** To fix the compiler warnings:
2a3,9
> %union {
> 	char *s;
> }
> 
> %type  <s> expr
> %token <s> A_STRING
> 
4c11
< %token A_STRING SUBSTR LENGTH INDEX NOARG MATCH
---
> %token SUBSTR LENGTH INDEX NOARG MATCH
90c97
< 	yylval = p;
---
> 	yylval.s = p;

-- 
{harvard,mit-eddie,think}!eplunix!earvax!das	David Allan Steffens
243 Charles St., Boston, MA 02114		Eaton-Peabody Laboratory
(617) 523-7900 x2748				Mass. Eye & Ear Infirmary



More information about the Net.bugs.v7 mailing list