From af084f375c5fd1a23760fae9fca59a74f90404a0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 3 Jun 2026 14:33:14 +1000 Subject: [PATCH] pad: ignore invalid strip axis values we call log2() on both maximum and value so ensure they're never zero or negative. Part-of: --- src/evdev-tablet-pad.c | 3 +++ test/test-pad.c | 49 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/evdev-tablet-pad.c b/src/evdev-tablet-pad.c index 7d8adca2..85f33ec2 100644 --- a/src/evdev-tablet-pad.c +++ b/src/evdev-tablet-pad.c @@ -237,6 +237,9 @@ normalize_wacom_ring(const struct input_absinfo *absinfo) static inline double normalize_wacom_strip(const struct input_absinfo *absinfo) { + if (absinfo->maximum <= 1 || absinfo->value <= 0) + return 0.0; + /* strip axes don't use a proper value, they just shift the bit left * for each position. 0 isn't a real value either, it's only sent on * finger release */ diff --git a/test/test-pad.c b/test/test-pad.c index 6c3560d6..3273025f 100644 --- a/test/test-pad.c +++ b/test/test-pad.c @@ -1113,6 +1113,54 @@ START_TEST(pad_keys) } END_TEST +START_TEST(pad_strip_wacom_degenerate_max) +{ + struct libinput_event *ev; + struct libinput_event_tablet_pad *pev; + double pos; + + /* Override ABS_RX to have maximum=1, which would cause + * log2(1) = 0 and division by zero in normalize_wacom_strip() + * without the guard. */ + /* clang-format off */ + struct input_absinfo abs_override[] = { + { ABS_RX, 0, 1, 0, 0, 0 }, + { -1, -1, -1, -1, -1, -1 }, + }; + /* clang-format on */ + + _litest_context_destroy_ struct libinput *li = litest_create_context(); + struct litest_device *dev = + litest_add_device_with_overrides(li, + LITEST_WACOM_INTUOS3_PAD, + NULL, + NULL, + abs_override, + NULL); + + litest_drain_events(li); + + /* Send strip events - value 1 with max 1 triggers + * log2(1)/log2(1) = 0/0 = NaN without the guard */ + litest_pad_strip_start(dev, 100); + litest_dispatch(li); + + ev = libinput_get_event(li); + pev = litest_is_pad_strip_event(ev, 0, LIBINPUT_TABLET_PAD_STRIP_SOURCE_FINGER); + pos = libinput_event_tablet_pad_get_strip_position(pev); + /* Without the fix, pos would be NaN from 0/0 division. + * With the fix, pos must be a valid finite number. */ + litest_assert_double_ge(pos, 0.0); + litest_assert_double_le(pos, 1.0); + libinput_event_destroy(ev); + + litest_pad_strip_end(dev); + litest_drain_events(li); + + litest_device_destroy(dev); +} +END_TEST + START_TEST(pad_send_events_disabled) { struct litest_device *dev = litest_current_device(); @@ -1171,6 +1219,7 @@ TEST_COLLECTION(pad) litest_add(pad_has_strip, LITEST_STRIP, LITEST_ANY); litest_add(pad_strip, LITEST_STRIP, LITEST_ANY); litest_add(pad_strip_finger_up, LITEST_STRIP, LITEST_ANY); + litest_add_no_device(pad_strip_wacom_degenerate_max); litest_add(pad_has_dial, LITEST_DIAL, LITEST_ANY); litest_add(pad_dial_low_res, LITEST_DIAL, LITEST_ANY);