Fix invalid comparator in event_strcmp_events()

The function event_strcmp_events was previously returning int values
(-1, 0, 1) to indicate ordering. While this may resemble strcmp-like
semantics, it is invalid when used as a comparator with std::sort.

According to the C++ standard, the comparator used in standard
algorithms must be a function object returning a value contextually
convertible to bool, where comp(a, b) returns true if and only if a is
considered less than b.

Returning -1, 0, or 1 violates these rules. In particular, std::sort()
only expects the comparator to return a boolean value, and it uses that
value to infer ordering. Returning an int may lead to incorrect sorting
behavior and undefined behavior, including segmentation faults.

Replace the int-style comparator with a strict boolean comparison to
comply with the standard and ensure sorting correctness.
This commit is contained in:
Kuan-Wei Chiu 2025-06-21 19:58:27 +08:00
parent b0067e8934
commit 5182645668

View file

@ -56,7 +56,7 @@ bool event_is_number(const char* s)
}
// compare /dev/input/eventX and /dev/input/eventY where X and Y are numbers
int event_strcmp_events(const char* x, const char* y)
bool event_cmp_less_than(const char* x, const char* y)
{
// find a common string
int n = 0;
@ -71,14 +71,10 @@ int event_strcmp_events(const char* x, const char* y)
const int a = atoi(x + n);
const int b = atoi(y + n);
if (a == b)
return 0;
if (a < b)
return -1;
return 1;
return a < b;
}
return strcmp(x, y);
return strcmp(x, y) < 0;
}
evdev_gun_handler::evdev_gun_handler()
@ -243,7 +239,7 @@ bool evdev_gun_handler::init()
// Sort the udev entries by devnode name so that they are created in the proper order
std::sort(sorted_devices.begin(), sorted_devices.end(), [](const event_udev_entry& a, const event_udev_entry& b)
{
return event_strcmp_events(a.devnode, b.devnode);
return event_cmp_less_than(a.devnode, b.devnode);
});
for (const event_udev_entry& entry : sorted_devices)