[net.bugs] XENIX 3.0 toupper

djl@fisher.UUCP (Dan Levin N6BZA ) (09/25/85)

Found this one while trying to make sendmail work,... all the lines of
the form
From:
To:
Date:
came out of the form
Rom:
O:
Ate:

Seems that the XENIX 3.0 ctype.h has toupper() and tolower() defined as
macros like this,...
#define toupper(x) (ifsomething(x) ? dosomething(x) : (x))
which breaks badly if (x) is autoincrement or autodecrement. Ie.
toupper(s++) goes to (ifsomething(s++) ? donesomething(s++) : (s++)),
which is clearly wrong.

The fix is to ctype.h, to not use the trinary operator; or to use the
libc versions instead (by #undef'ing toupper() and tolower());

NB:  This only holds for the Intel distribution, I have not checked the
IBM XENIX 3.0 release.

-- 
			***dan

{allegra,astrovax,princeton,twg}!fisher!djl
The misplaced (You call *that* a ski slope??) Californian

rlk@chinet.UUCP (Richard L. Klappal) (09/28/85)

In article <764@fisher.UUCP> djl@fisher.UUCP (Dan Levin  N6BZA ) writes:
>Seems that the XENIX 3.0 ctype.h has toupper() and tolower() defined as
>macros like this,...
>#define toupper(x) (ifsomething(x) ? dosomething(x) : (x))
>which breaks badly if (x) is autoincrement or autodecrement. Ie.
>toupper(s++) goes to (ifsomething(s++) ? donesomething(s++) : (s++)),
>which is clearly wrong.
>
>The fix is to ctype.h, to not use the trinary operator; or to use the
>libc versions instead (by #undef'ing toupper() and tolower());
>
>NB:  This only holds for the Intel distribution, I have not checked the
>IBM XENIX 3.0 release.
>
>-- 
>			***dan
>
>{allegra,astrovax,princeton,twg}!fisher!djl
>The misplaced (You call *that* a ski slope??) Californian

This is not the only bug running around in toupper/tolower.  While
some systems have this implementation, other versions (among which
is the Fortune) do not do any sanity check, they just add/subtract
0x20, thus transforming numerals into control codes or letters,
depending on the direction of conversion.  Harbison & Steele warn
that toupper/tolower are inconsistant between versions if *NIX. and
indicate what they suggested (?? SYSV ?? ANSI ) recommendations are.

My answer has been my own local ROUTINES (not macros) named 
'ucase' and 'lcase' that do the sanity check and compute the
result.  It causes a little redundant code on machines that work
right, but is nice insurance anyplace they don't, without conflicting
with the internal names (viz. tolower or _tolower, etc).

(Apologies if I misspelled either of the names above, it doesn't
look right, but the book is upstairs)

-- 

Richard Klappal

UUCP:		..!ihnp4!chinet!uklpl!rlk  | "Money is truthful.  If a man
MCIMail:	rklappal		   | speaks of his honor, make him
Compuserve:	74106,1021		   | pay cash."
USPS:		1 S 299 Danby Street	   | 
		Villa Park IL 60181	   |	Lazarus Long 
TEL:		(312) 620-4988		   |	    (aka R. Heinlein)
-------------------------------------------------------------------------

tg@sfmin.UUCP (T.Glinos) (09/29/85)

> Found this one while trying to make sendmail work,... all the lines of
> the form
> From:
> To:
> Date:
> came out of the form
> Rom:
> O:
> Ate:
> 
> Seems that the XENIX 3.0 ctype.h has toupper() and tolower() defined as
> macros like this,...
> #define toupper(x) (ifsomething(x) ? dosomething(x) : (x))
> which breaks badly if (x) is autoincrement or autodecrement. Ie.
> toupper(s++) goes to (ifsomething(s++) ? donesomething(s++) : (s++)),
> which is clearly wrong.
> 
> The fix is to ctype.h, to not use the trinary operator; or to use the
> libc versions instead (by #undef'ing toupper() and tolower());
> 
> NB:  This only holds for the Intel distribution, I have not checked the
> IBM XENIX 3.0 release.
> 
> -- 
> 			***dan
> 
> {allegra,astrovax,princeton,twg}!fisher!djl
> The misplaced (You call *that* a ski slope??) Californian

*** REPLACE THIS LINE WITH YOUR MESSAGE ***
XENIX System V has this all fixed.

henry@utzoo.UUCP (Henry Spencer) (10/01/85)

> This is not the only bug running around in toupper/tolower.  While
> some systems have this implementation, other versions (among which
> is the Fortune) do not do any sanity check, they just add/subtract
> 0x20, thus transforming numerals into control codes or letters,
> depending on the direction of conversion...

This was the original definition of toupper/tolower.  It was not a bug;
the domain of legal arguments was letters of the opposite case, period.
This way if you knew the nature of the argument, the overhead of the
check was unnecessary; if you didn't, you were supposed to do the check
first.  So many people were sloppy about it that inadequate domain
checking became a characteristic error when using these macros.  So the
definition was eventually changed.  Implementations that don't check are
not buggy:  they are conforming correctly to an earlier, and arguably less
desirable (certainly less idiot-proof), version of the specs.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

addw@root44.UUCP (Alain Williams) (10/02/85)

>> Seems that the XENIX 3.0 ctype.h has toupper() and tolower() defined as
>> macros like this,...
>> #define toupper(x) (ifsomething(x) ? dosomething(x) : (x))
>> which breaks badly if (x) is autoincrement or autodecrement. Ie.
>> toupper(s++) goes to (ifsomething(s++) ? donesomething(s++) : (s++)),
>> which is clearly wrong.

This is clearly right. When you are dealing with macros, you must always
expect this. The fact that it broke news software is a reflection on the
way news was written, not the XENIX macros.
-- 
	Alain Williams,
	Root Computers Ltd, London, England.
	<UK-net>!{hrc63|qmc-cs|edai|kcl-cs|ukc|glasgow|ist|jmccfr|west44
		ubu|rlvd|pmllab|stc}!root44!addw
	{unisoft|deccra}!root44!addw
	root44!{rootcl|rootis}!addw