"Gary E. Miller" <[email protected]> writes:
>> Yes, but you didn't quote enough. It says:
>>
>> The c argument is a type int, the value of which the application
>> shall ensure is a character representable as an unsigned char or
>> equal to the value of the macro EOF. If the argument has any other
>> value, the behavior is undefined.
>
> GNU libc hhas no such caveat. C99 also does not.
GNU libc might well do something else; that's within UB and no
violation. But it's not an argument that the code is ok.
I don't have access to the released version of C99, but in draft
n1256, that text is in 7.4 "Character handling <ctype.h>" said to apply
to all of the ctype functions.
> C23 doe say:
>
> "In all cases the argument is an int, the value of which shall be
> representable as an unsigned char or shall equal the value of the macro
> EOF. If the argument has any other value, the behavior is undefined. "
Word for word same as C99 7.4
> Since gpsd only passed a char or unsigned char to isXXXX(), that is
> satisfied. Those are simply promoted to int, so need no cast.
Not quite and that's why this is tricky. When a (signed) char is
promoted to int, any negative values end up as negative ints, and those
are not representable as unsigned char.
>> This leads to the general rule that you can't use arguments of type
>> char for ctype functions. If it's a char, it needs to be cast to
>> unsigned char. There are a massive number of such constructions
>> already in the code.
>
> Id be happy to ensure gpsd is always using uchar for anything going
> to isXXXXX(); Old gpsd code is very sloppy about char vs uchar.
There is a tremendous amount of such code out there, not specific to
gpsd. Basically when passing a variable of type char (or expression),
cast it to unsigned char, which moves the negative values to the 128-255
range.
>> libgps/gpsutils.c: if (isdigit((unsigned char)*p)) {
>
> Yeah, those are just wrong. I did not expect to get them all
> on the first pass. I'll rip those out today.
The code I pasted is right. It's leaving it out tht's a bug.