Subject: Re: lib/19638: isalpha (3) bug
To: Dave Sainty <dave@dtsp.co.nz>
From: Mike Cheponis <mac@Wireless.Com>
List: netbsd-bugs
Date: 01/03/2003 14:15:31
On Fri, 3 Jan 2003, Dave Sainty wrote:
> > HOWEVER, the behavior on NetBSD is still wrong, I maintain. Here's my
> > argument:
>...
> This is hardly a real-world example though!
Ahh, who's to say it isn't "real-world"? I found this NetBSD bug while
using srandom() and random().
The NetBSD behaviour is wrong.
> > 1) Here are the OSs that this program works without a problem:
> >
> > o Digital UNIX V4.0B (Rev. 564); Tue Dec 14 15:43:30 EST 1999
> > o FreeBSD 4.2-RELEASE #2: Sun Mar 4 12:11:05 PST 2001
> > o BSDI BSD/OS 4.0 Kernel #6: Thu Jan 21 12:47:23 PST 1999
> I think you'll find that they are all behaving the same. That is,
> they are all behaving in an undefined manner. For some, that doesn't
> involve crashing (but not crashing is arguably a less appropriate
> response than crashing).
I did the tests, and your assertion is incorrect. Here is the test prog:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main()
{
int c;
for (c=0; c <= 0x7ffffff; c++){
if (isalpha(c)){printf ("%c(%d)\n",c); fflush(stdout);}
}
return 0;
}
Both FreeBSD and BSDI produce exactly what one would expect: A-Z then a-z.
(Digital unix was confused).
>
> > ==> Argument Second: Although I'm all for "programming by contract" as a
> > programming dicipline, I believe that we need to treat libc as meeting
> > a "higher standard".
> >
> > In particular, libc should not violate the Principal of Least
> > Astonishment, which it clearly does here.
>
> Surely it isn't that astonishing that passing arbitrary values in
> where a character was expected might cause the program to fail...
> That just isn't clear at all to me.
But, but, but.... if a "character" were expected, then one should pass a
char! But, we pass an int because the original designers of C were confusing
out-of-band information with data types.
But if we're stuck with this confusion, at -least- we can do is have the
libraries behave correctly, like FreeBSD and BSDI do.
>
> Absolutely, it should be documented, and it was an ommission in your
> cut of the manual page that it didn't mention the argument limits.
> But that's been corrected now...
A doc change is better than it was. "It's not a bug, it's documented!" -
sign - NOT the "NetBSD Way" I would continue to say...
>
> > Feeding a routine in libc a perfectly valid int should NOT cause the
> > libc routine to segfault. That is Bad.
>
> isalpha(c) doesn't take an integer, it takes a character or EOF. You
> aren't feeding in perfectly valid characters...
But, but, but... see above.
> > ==> Argument Third: I don't care if I see bat-out-of-hell performance if
> > the result is wrong. (The suggested mod, above, I believe would not
> > noticeably slow down any but the most pathological programs.)
>
> The result isn't wrong, it's perfectly valid. You'll see the same
> result in many C library interfaces (try passing "perfectly valid
> pointers" into fread() and your program will crash too).
Pointers are a whole different ballgame. I'm talking about simple typed
arguments here.
> Only pathological programs are going to trip over this, and in every
> case that program is buggy and needs to be fixed. You're abusing the
> interface. On a considerable proportion of systems that will result
> in a crash for the ctype.h functions.
Your assertions are not at all true. (!)
****NetBSD**** is abusing the interface by having libc crash when perfectly
legal values of the type are sent to a routine in libc.
FreeBSD and BSDI don't have this bug; why does NetBSD ?
> Cheers,
>
> Dave
Thanks, -Mike