[PATCH] evdev: Array sizes and iterations off by one

Matt Helsley matt.helsley at gmail.com
Sat Jan 10 23:05:12 PST 2009


ABS_CNT (and friends) need to be used in some places instead of
ABS_MAX. Also "NBITS" seems misnamed -- it is really the number of
longs needed to hold the specified number of bits.

Signed-off-by: Matt Helsley <matt.helsley at gmail.com>
---
 src/evdev.c |   24 ++++++++++++------------
 src/evdev.h |   30 +++++++++++++++++++++++-------
 2 files changed, 35 insertions(+), 19 deletions(-)

Index: xf86-input-evdev/src/evdev.h
===================================================================
--- xf86-input-evdev.orig/src/evdev.h
+++ xf86-input-evdev/src/evdev.h
@@ -38,18 +38,34 @@
 
 #ifdef XKB
 #include <xkbstr.h>
 #endif
 
+#ifndef EV_CNT /* linux 2.4 kernels and earlier lack _CNT defines */
+#define EV_CNT (EV_MAX+1)
+#endif
+#ifndef KEY_CNT
+#define KEY_CNT (KEY_MAX+1)
+#endif
+#ifndef REL_CNT
+#define REL_CNT (REL_MAX+1)
+#endif
+#ifndef ABS_CNT
+#define ABS_CNT (ABS_MAX+1)
+#endif
+#ifndef LED_CNT
+#define LED_CNT (LED_MAX+1)
+#endif
+
 #define EVDEV_MAXBUTTONS 32
 
 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
 #define HAVE_PROPERTIES 1
 #endif
 
 #define LONG_BITS (sizeof(long) * 8)
-#define NBITS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
+#define NLONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
 
 /* axis specific data for wheel emulation */
 typedef struct {
     int up_button;
     int down_button;
@@ -118,16 +134,16 @@ typedef struct {
     int reopen_left;     /* number of attempts left to re-open the device */
     OsTimerPtr reopen_timer;
 
     /* Cached info from device. */
     char name[1024];
-    long bitmask[NBITS(EV_MAX)];
-    long key_bitmask[NBITS(KEY_MAX)];
-    long rel_bitmask[NBITS(REL_MAX)];
-    long abs_bitmask[NBITS(ABS_MAX)];
-    long led_bitmask[NBITS(LED_MAX)];
-    struct input_absinfo absinfo[ABS_MAX];
+    long bitmask[NLONGS(EV_MAX)];
+    long key_bitmask[NLONGS(KEY_MAX)];
+    long rel_bitmask[NLONGS(REL_MAX)];
+    long abs_bitmask[NLONGS(ABS_MAX)];
+    long led_bitmask[NLONGS(LED_MAX)];
+    struct input_absinfo absinfo[ABS_CNT];
 
     /* minor/major number */
     dev_t min_maj;
 } EvdevRec, *EvdevPtr;
 
Index: xf86-input-evdev/src/evdev.c
===================================================================
--- xf86-input-evdev.orig/src/evdev.c
+++ xf86-input-evdev/src/evdev.c
@@ -234,18 +234,18 @@ PostButtonClicks(InputInfoPtr pInfo, int
 
 static void
 PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
 {
     int code = ev->code + MIN_KEYCODE;
-    static char warned[KEY_MAX];
+    static char warned[KEY_CNT];
 
     /* Filter all repeated events from device.
        We'll do softrepeat in the server */
     if (value == 2)
 	return;
 
-    if (code > 255 && ev->code < KEY_MAX) {
+    if (code > 255 && ev->code < KEY_CNT) {
 	if (!warned[ev->code])
 	    xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
 		    pInfo->name, ev->code);
 	warned[ev->code] = 1;
     }
@@ -1193,16 +1193,16 @@ EvdevCacheCompare(InputInfoPtr pInfo, BO
 {
     EvdevPtr pEvdev = pInfo->private;
     int i;
 
     char name[1024]                  = {0};
-    long bitmask[NBITS(EV_MAX)]      = {0};
-    long key_bitmask[NBITS(KEY_MAX)] = {0};
-    long rel_bitmask[NBITS(REL_MAX)] = {0};
-    long abs_bitmask[NBITS(ABS_MAX)] = {0};
-    long led_bitmask[NBITS(LED_MAX)] = {0};
-    struct input_absinfo absinfo[ABS_MAX];
+    long bitmask[NLONGS(EV_MAX)]      = {0};
+    long key_bitmask[NLONGS(KEY_MAX)] = {0};
+    long rel_bitmask[NLONGS(REL_MAX)] = {0};
+    long abs_bitmask[NLONGS(ABS_MAX)] = {0};
+    long led_bitmask[NLONGS(LED_MAX)] = {0};
+    struct input_absinfo absinfo[ABS_CNT];
 
     if (ioctl(pInfo->fd,
               EVIOCGNAME(sizeof(name) - 1), name) < 0) {
         xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
         goto error;
@@ -1257,11 +1257,11 @@ EvdevCacheCompare(InputInfoPtr pInfo, BO
     if (compare && memcmp(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask)))
         goto error;
 
     memset(absinfo, 0, sizeof(absinfo));
 
-    for (i = 0; i < ABS_MAX; i++)
+    for (i = 0; i < ABS_CNT; i++)
     {
         if (TestBit(i, abs_bitmask))
         {
             if (ioctl(pInfo->fd, EVIOCGABS(i), &absinfo[i]) < 0) {
                 xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno));
@@ -1293,13 +1293,13 @@ error:
 }
 
 static int
 EvdevProbe(InputInfoPtr pInfo)
 {
-    long key_bitmask[NBITS(KEY_MAX)] = {0};
-    long rel_bitmask[NBITS(REL_MAX)] = {0};
-    long abs_bitmask[NBITS(ABS_MAX)] = {0};
+    long key_bitmask[NLONGS(KEY_MAX)] = {0};
+    long rel_bitmask[NLONGS(REL_MAX)] = {0};
+    long abs_bitmask[NLONGS(ABS_MAX)] = {0};
     int i, has_axes, has_keys, num_buttons, has_scroll;
     int kernel24 = 0;
     EvdevPtr pEvdev = pInfo->private;
 
     if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {





More information about the xorg mailing list