[PATCH] Fix FOO_MAX off-by-one
Peter Hutterer
peter.hutterer at who-t.net
Sun Jan 11 19:29:55 PST 2009
On Sun, Jan 11, 2009 at 06:36:59PM -0800, Matt Helsley wrote:
> In linux/input.h each section's (e.g. ABS) FOO_MAX is the maximum FOO
> value. Recent kernels define FOO_CNT as the maximum number of FOO there
> will ever be. Hence using FOO_MAX to size the bit vectors representing
> the capabilities of an evdev device is off by one.
>
> Define FOO_CNT values for use with Linux kernels which lack them. Use
> FOO_CNT whenever we need to know the number of bits needed -- usually to
> calculate the number of longs needed.
>
> When iterating over the values FOO_MAX still seems appropriate however
> the loop test should include FOO_MAX rather than skip it.
>
Pushed as 4dfd86b2201b2b19761a1abb3c580cecf0060224, thanks.
> Signed-off-by: Matt Helsley <matt.helsley at gmail.com>
> ---
> src/evdev.c | 24 ++++++++++++------------
> src/evdev.h | 28 ++++++++++++++++++++++------
> 2 files changed, 34 insertions(+), 18 deletions(-)
>
> 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_MAX) {
> if (!warned[ev->code])
> xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
> pInfo->name, ev->code);
> warned[ev->code] = 1;
> }
> @@ -1221,16 +1221,16 @@ EvdevCacheCompare(InputInfoPtr pInfo, BO
> {
> EvdevPtr pEvdev = pInfo->private;
> int i;
>
> char name[1024] = {0};
> - 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_MAX];
> + long bitmask[NLONGS(EV_CNT)] = {0};
> + long key_bitmask[NLONGS(KEY_CNT)] = {0};
> + long rel_bitmask[NLONGS(REL_CNT)] = {0};
> + long abs_bitmask[NLONGS(ABS_CNT)] = {0};
> + long led_bitmask[NLONGS(LED_CNT)] = {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;
> @@ -1285,11 +1285,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 = ABS_X; i <= ABS_MAX; 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));
> @@ -1321,13 +1321,13 @@ error:
> }
>
> static int
> EvdevProbe(InputInfoPtr pInfo)
> {
> - long key_bitmask[NLONGS(KEY_MAX)] = {0};
> - long rel_bitmask[NLONGS(REL_MAX)] = {0};
> - long abs_bitmask[NLONGS(ABS_MAX)] = {0};
> + long key_bitmask[NLONGS(KEY_CNT)] = {0};
> + long rel_bitmask[NLONGS(REL_CNT)] = {0};
> + long abs_bitmask[NLONGS(ABS_CNT)] = {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)) {
> Index: xf86-input-evdev/src/evdev.h
> ===================================================================
> --- xf86-input-evdev.orig/src/evdev.h
> +++ xf86-input-evdev/src/evdev.h
> @@ -38,10 +38,26 @@
>
> #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
> @@ -121,16 +137,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[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_MAX];
> + long bitmask[NLONGS(EV_CNT)];
> + long key_bitmask[NLONGS(KEY_CNT)];
> + long rel_bitmask[NLONGS(REL_CNT)];
> + long abs_bitmask[NLONGS(ABS_CNT)];
> + long led_bitmask[NLONGS(LED_CNT)];
> + struct input_absinfo absinfo[ABS_CNT];
>
> /* minor/major number */
> dev_t min_maj;
> } EvdevRec, *EvdevPtr;
>
More information about the xorg
mailing list