summaryrefslogtreecommitdiff
path: root/libevdev/libevdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'libevdev/libevdev.c')
-rw-r--r--libevdev/libevdev.c24
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;