xfree86: Fix event data alignment in inputtest driver
This fixes address sanitizer errors when running unit tests. The additional copying may reduce performance by a small amount, but we don't care about that because this driver is used for testing only. Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
This commit is contained in:
parent
43e934a19f
commit
7d2014e7d5
|
@ -856,39 +856,48 @@ read_input_from_connection(InputInfoPtr pInfo)
|
||||||
driver_data->buffer.valid_length += read_size;
|
driver_data->buffer.valid_length += read_size;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
xf86ITEventHeader *event_header;
|
xf86ITEventHeader event_header;
|
||||||
char *event_begin = driver_data->buffer.data + processed_size;
|
char *event_begin = driver_data->buffer.data + processed_size;
|
||||||
|
|
||||||
if (driver_data->buffer.valid_length - processed_size < sizeof(xf86ITEventHeader))
|
if (driver_data->buffer.valid_length - processed_size < sizeof(xf86ITEventHeader))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
event_header = (xf86ITEventHeader*) event_begin;
|
/* Note that event_begin pointer is not aligned, accessing it directly is
|
||||||
|
undefined behavior. We must use memcpy to copy the data to aligned data
|
||||||
|
area. Most compilers will optimize out this call out and use whatever
|
||||||
|
is most efficient to access unaligned data on a particular platform */
|
||||||
|
memcpy(&event_header, event_begin, sizeof(xf86ITEventHeader));
|
||||||
|
|
||||||
if (event_header->length >= EVENT_BUFFER_SIZE) {
|
if (event_header.length >= EVENT_BUFFER_SIZE) {
|
||||||
xf86IDrvMsg(pInfo, X_ERROR, "Received event with too long length: %d\n",
|
xf86IDrvMsg(pInfo, X_ERROR, "Received event with too long length: %d\n",
|
||||||
event_header->length);
|
event_header.length);
|
||||||
teardown_client_connection(pInfo);
|
teardown_client_connection(pInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver_data->buffer.valid_length - processed_size < event_header->length)
|
if (driver_data->buffer.valid_length - processed_size < event_header.length)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (is_supported_event(event_header->type)) {
|
if (is_supported_event(event_header.type)) {
|
||||||
int expected_event_size = get_event_size(event_header->type);
|
int expected_event_size = get_event_size(event_header.type);
|
||||||
|
|
||||||
if (event_header->length != expected_event_size) {
|
if (event_header.length != expected_event_size) {
|
||||||
xf86IDrvMsg(pInfo, X_ERROR, "Unexpected event length: was %d bytes, "
|
xf86IDrvMsg(pInfo, X_ERROR, "Unexpected event length: was %d bytes, "
|
||||||
"expected %d (event type: %d)\n",
|
"expected %d (event type: %d)\n",
|
||||||
event_header->length, expected_event_size,
|
event_header.length, expected_event_size,
|
||||||
(int) event_header->type);
|
(int) event_header.type);
|
||||||
teardown_client_connection(pInfo);
|
teardown_client_connection(pInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_event(pInfo, (xf86ITEventAny*) event_begin);
|
/* We could use event_begin pointer directly, but we want to ensure correct
|
||||||
|
data alignment (if only so that address sanitizer does not complain) */
|
||||||
|
xf86ITEventAny event_data;
|
||||||
|
memset(&event_data, 0, sizeof(event_data));
|
||||||
|
memcpy(&event_data, event_begin, event_header.length);
|
||||||
|
handle_event(pInfo, &event_data);
|
||||||
}
|
}
|
||||||
processed_size += event_header->length;
|
processed_size += event_header.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processed_size > 0) {
|
if (processed_size > 0) {
|
||||||
|
|
Loading…
Reference in New Issue