diff options
Diffstat (limited to 'libevdev/libevdev.c')
-rw-r--r-- | libevdev/libevdev.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/libevdev/libevdev.c b/libevdev/libevdev.c index a77c466..d9e2517 100644 --- a/libevdev/libevdev.c +++ b/libevdev/libevdev.c @@ -809,6 +809,26 @@ read_more_events(struct libevdev *dev) return 0; } +/** + * Sanitize/modify events where needed. + * @return 0 if untouched, 1 if modified. + */ +static inline int +sanitize_event(const struct libevdev *dev, struct input_event *ev) +{ + if (unlikely(dev->num_slots > -1 && + libevdev_event_is_code(ev, EV_ABS, ABS_MT_SLOT) && + (ev->value < 0 || ev->value >= dev->num_slots))) { + log_bug("Device %s received an invalid slot index %d." + "Capping to announced max slot number %d.\n", + dev->name, ev->value, dev->num_slots - 1); + ev->value = dev->num_slots - 1; + return 1; + } + + return 0; +} + LIBEVDEV_EXPORT int libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event *ev) { @@ -875,6 +895,7 @@ libevdev_next_event(struct libevdev *dev, unsigned int flags, struct input_event if (queue_shift(dev, ev) != 0) return -EAGAIN; + sanitize_event(dev, ev); update_state(dev, ev); /* if we disabled a code, get the next event instead */ @@ -1072,6 +1093,9 @@ libevdev_set_event_value(struct libevdev *dev, unsigned int type, unsigned int c e.code = code; e.value = value; + if (sanitize_event(dev, &e)) + return -1; + switch(type) { case EV_ABS: rc = update_abs_state(dev, &e); break; case EV_KEY: rc = update_key_state(dev, &e); break; |