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