changeset 3404:c9dcc73f6a36

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
author Sam Lantinga <slouken@libsdl.org>
date Sun, 18 Oct 2009 16:14:35 +0000
parents 5f812979e179
children d5f2dd33f4eb
files src/joystick/linux/SDL_sysjoystick.c
diffstat 1 files changed, 8 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/joystick/linux/SDL_sysjoystick.c	Sat Oct 17 23:29:52 2009 +0000
+++ b/src/joystick/linux/SDL_sysjoystick.c	Sun Oct 18 16:14:35 2009 +0000
@@ -366,14 +366,15 @@
 
 #if SDL_INPUT_LINUXEV
 #define test_bit(nr, addr) \
-	(((1UL << ((nr) & 31)) & (((const Uint32 *) addr)[(nr) >> 5])) != 0)
+	(((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
+#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
 
 static int
 EV_IsJoystick(int fd)
 {
-    unsigned long evbit[40];
-    unsigned long keybit[40];
-    unsigned long absbit[40];
+    unsigned long evbit[NBITS(EV_MAX)] = { 0 };
+    unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
+    unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
 
     if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
         (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
@@ -664,9 +665,9 @@
 EV_ConfigJoystick(SDL_Joystick * joystick, int fd)
 {
     int i, t;
-    unsigned long keybit[40];
-    unsigned long absbit[40];
-    unsigned long relbit[40];
+    unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
+    unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
+    unsigned long relbit[NBITS(REL_MAX)] = { 0 };
 
     /* See if this device uses the new unified event API */
     if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) &&