Fixed bug #853 SDL-1.2
authorSam Lantinga <slouken@libsdl.org>
Sun, 18 Oct 2009 16:14:57 +0000
branchSDL-1.2
changeset 4352c8bf421431f9
parent 4351 3ae3624c3cbc
child 4353 da1ef6acde9e
Fixed bug #853

Ludwig Nussel 2009-10-18 05:34:18 PDT

src/joystick/linux/SDL_sysjoystick.c has some problems:

- test_bit() might break with strict aliasing
- test_bit() assumes array is Uint32 but its actually "unsigned long"
on 64bit systems sizeof(long) != sizeof(Uint32).
- the keybit array is too small
- the arrays are unitialized so the number of
detected buttons is quite random
src/joystick/linux/SDL_sysjoystick.c
     1.1 --- a/src/joystick/linux/SDL_sysjoystick.c	Sat Oct 17 17:35:48 2009 +0000
     1.2 +++ b/src/joystick/linux/SDL_sysjoystick.c	Sun Oct 18 16:14:57 2009 +0000
     1.3 @@ -374,13 +374,14 @@
     1.4  
     1.5  #if SDL_INPUT_LINUXEV
     1.6  #define test_bit(nr, addr) \
     1.7 -	(((1UL << ((nr) & 31)) & (((const Uint32 *) addr)[(nr) >> 5])) != 0)
     1.8 +	(((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
     1.9 +#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
    1.10  
    1.11  static int EV_IsJoystick(int fd)
    1.12  {
    1.13 -	unsigned long evbit[40];
    1.14 -	unsigned long keybit[40];
    1.15 -	unsigned long absbit[40];
    1.16 +	unsigned long evbit[NBITS(EV_MAX)] = { 0 };
    1.17 +	unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
    1.18 +	unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
    1.19  
    1.20  	if ( (ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
    1.21  	     (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
    1.22 @@ -661,9 +662,9 @@
    1.23  static SDL_bool EV_ConfigJoystick(SDL_Joystick *joystick, int fd)
    1.24  {
    1.25  	int i, t;
    1.26 -	unsigned long keybit[40];
    1.27 -	unsigned long absbit[40];
    1.28 -	unsigned long relbit[40];
    1.29 +	unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
    1.30 +	unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
    1.31 +	unsigned long relbit[NBITS(REL_MAX)] = { 0 };
    1.32  
    1.33  	/* See if this device uses the new unified event API */
    1.34  	if ( (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&