your mail
Rob Landley
rob at landley.net
Fri Jan 16 03:41:55 UTC 2009
On Wednesday 14 January 2009 18:12:32 Khem Raj wrote:
> On (14/01/09 17:07), Natanael Copa wrote:
> > Hi,
> >
> > This test program segfaults for me on x86, hardened gcc-4.3.2 and
> > uclibc-0.9.30:
> >
> > #include <stdio.h>
> > #include <ctype.h>
> > int main(void) {
> > printf("%i\n", isalnum(0x10000));
> > return 0;
> > }
> >
> >
> > If the ctype.h include is commented out it works as expected.
>
> This sounds a bug to me.
> with ctype.h included it used the isalnum macro which
> then does a lookup in an array of 256 elements and the argument serves
> as array index which in your case is 0x10000 is way beyond the size of
> array.
>
> Currently if you use the valid range i.e upto 255 it will work as
> expected but beyond that it will be accessing outside the array and you
> will get random values.
>
> If you do not include ctype.h then it falls back to normal libc
> implementation which works and handles the cases beyond the ASCII range
Other fun corner case is that if char is signed your range could go from -128
through +127. The way glibc handled this was to make the array 384 entries
long, and here's a cut and paste from /usr/include/ctype.h from glibc
explaining why they did that:
/*
These point into arrays of 384, so they can be indexed by any `unsigned
char' value [0,255]; by EOF (-1); or by any `signed char' value
[-128,-1). ISO C requires that the ctype functions work for `unsigned
char' values and for EOF; we also support negative `signed char' values
for broken old programs. The case conversion arrays are of `int's
rather than `unsigned char's because tolower (EOF) must be EOF, which
doesn't fit into an `unsigned char'. But today more important is that
the arrays are also used for multi-byte character sets. */
Whether or not it's a good solution I'll stay out of. :)
Rob
More information about the uClibc
mailing list