hidapi: fix function pointer type mismatch in backend table

The HIDAPI backend table used function pointers that didn't match the
macro-renamed backend function types, which trips Clang's function sanitizer.

Adding small wrappers so the backend table has the correct function types and
the cast to the backend-specific device type happens inside a direct call.
fixes #15821.
This commit is contained in:
arnau.nau
2026-06-13 12:25:45 +02:00
committed by Sam Lantinga
parent 9c30a7cc82
commit 46d0ecead0

View File

@@ -900,83 +900,153 @@ static bool use_libusb_gamecube = true;
struct hidapi_backend
{
int (*hid_write)(void *device, const unsigned char *data, size_t length);
int (*hid_read_timeout)(void *device, unsigned char *data, size_t length, int milliseconds);
int (*hid_read)(void *device, unsigned char *data, size_t length);
int (*hid_set_nonblocking)(void *device, int nonblock);
int (*hid_send_feature_report)(void *device, const unsigned char *data, size_t length);
int (*hid_get_feature_report)(void *device, unsigned char *data, size_t length);
int (*hid_get_input_report)(void *device, unsigned char *data, size_t length);
void (*hid_close)(void *device);
int (*hid_get_manufacturer_string)(void *device, wchar_t *string, size_t maxlen);
int (*hid_get_product_string)(void *device, wchar_t *string, size_t maxlen);
int (*hid_get_serial_number_string)(void *device, wchar_t *string, size_t maxlen);
int (*hid_get_indexed_string)(void *device, int string_index, wchar_t *string, size_t maxlen);
struct hid_device_info *(*hid_get_device_info)(void *device);
int (*hid_get_report_descriptor)(void *device, unsigned char *buf, size_t buf_size);
const wchar_t *(*hid_error)(void *device);
int (*hid_write)(hid_device *device, const unsigned char *data, size_t length);
int (*hid_read_timeout)(hid_device *device, unsigned char *data, size_t length, int milliseconds);
int (*hid_read)(hid_device *device, unsigned char *data, size_t length);
int (*hid_set_nonblocking)(hid_device *device, int nonblock);
int (*hid_send_feature_report)(hid_device *device, const unsigned char *data, size_t length);
int (*hid_get_feature_report)(hid_device *device, unsigned char *data, size_t length);
int (*hid_get_input_report)(hid_device *device, unsigned char *data, size_t length);
void (*hid_close)(hid_device *device);
int (*hid_get_manufacturer_string)(hid_device *device, wchar_t *string, size_t maxlen);
int (*hid_get_product_string)(hid_device *device, wchar_t *string, size_t maxlen);
int (*hid_get_serial_number_string)(hid_device *device, wchar_t *string, size_t maxlen);
int (*hid_get_indexed_string)(hid_device *device, int string_index, wchar_t *string, size_t maxlen);
struct hid_device_info *(*hid_get_device_info)(hid_device *device);
int (*hid_get_report_descriptor)(hid_device *device, unsigned char *buf, size_t buf_size);
const wchar_t *(*hid_error)(hid_device *device);
};
#define HIDAPI_BACKEND_WRAPPERS(PREFIX, DEVICE_TYPE) \
static int PREFIX##_hid_write_backend(hid_device *device, const unsigned char *data, size_t length) \
{ \
return PREFIX##_hid_write((DEVICE_TYPE *)device, data, length); \
} \
static int PREFIX##_hid_read_timeout_backend(hid_device *device, unsigned char *data, size_t length, int milliseconds) \
{ \
return PREFIX##_hid_read_timeout((DEVICE_TYPE *)device, data, length, milliseconds); \
} \
static int PREFIX##_hid_read_backend(hid_device *device, unsigned char *data, size_t length) \
{ \
return PREFIX##_hid_read((DEVICE_TYPE *)device, data, length); \
} \
static int PREFIX##_hid_set_nonblocking_backend(hid_device *device, int nonblock) \
{ \
return PREFIX##_hid_set_nonblocking((DEVICE_TYPE *)device, nonblock); \
} \
static int PREFIX##_hid_send_feature_report_backend(hid_device *device, const unsigned char *data, size_t length) \
{ \
return PREFIX##_hid_send_feature_report((DEVICE_TYPE *)device, data, length); \
} \
static int PREFIX##_hid_get_feature_report_backend(hid_device *device, unsigned char *data, size_t length) \
{ \
return PREFIX##_hid_get_feature_report((DEVICE_TYPE *)device, data, length); \
} \
static int PREFIX##_hid_get_input_report_backend(hid_device *device, unsigned char *data, size_t length) \
{ \
return PREFIX##_hid_get_input_report((DEVICE_TYPE *)device, data, length); \
} \
static void PREFIX##_hid_close_backend(hid_device *device) \
{ \
PREFIX##_hid_close((DEVICE_TYPE *)device); \
} \
static int PREFIX##_hid_get_manufacturer_string_backend(hid_device *device, wchar_t *string, size_t maxlen) \
{ \
return PREFIX##_hid_get_manufacturer_string((DEVICE_TYPE *)device, string, maxlen); \
} \
static int PREFIX##_hid_get_product_string_backend(hid_device *device, wchar_t *string, size_t maxlen) \
{ \
return PREFIX##_hid_get_product_string((DEVICE_TYPE *)device, string, maxlen); \
} \
static int PREFIX##_hid_get_serial_number_string_backend(hid_device *device, wchar_t *string, size_t maxlen) \
{ \
return PREFIX##_hid_get_serial_number_string((DEVICE_TYPE *)device, string, maxlen); \
} \
static int PREFIX##_hid_get_indexed_string_backend(hid_device *device, int string_index, wchar_t *string, size_t maxlen) \
{ \
return PREFIX##_hid_get_indexed_string((DEVICE_TYPE *)device, string_index, string, maxlen); \
} \
static struct hid_device_info *PREFIX##_hid_get_device_info_backend(hid_device *device) \
{ \
return PREFIX##_hid_get_device_info((DEVICE_TYPE *)device); \
} \
static int PREFIX##_hid_get_report_descriptor_backend(hid_device *device, unsigned char *buf, size_t buf_size) \
{ \
return PREFIX##_hid_get_report_descriptor((DEVICE_TYPE *)device, buf, buf_size); \
} \
static const wchar_t *PREFIX##_hid_error_backend(hid_device *device) \
{ \
return PREFIX##_hid_error((DEVICE_TYPE *)device); \
}
#ifdef HAVE_PLATFORM_BACKEND
HIDAPI_BACKEND_WRAPPERS(PLATFORM, PLATFORM_hid_device)
static const struct hidapi_backend PLATFORM_Backend = {
(void *)PLATFORM_hid_write,
(void *)PLATFORM_hid_read_timeout,
(void *)PLATFORM_hid_read,
(void *)PLATFORM_hid_set_nonblocking,
(void *)PLATFORM_hid_send_feature_report,
(void *)PLATFORM_hid_get_feature_report,
(void *)PLATFORM_hid_get_input_report,
(void *)PLATFORM_hid_close,
(void *)PLATFORM_hid_get_manufacturer_string,
(void *)PLATFORM_hid_get_product_string,
(void *)PLATFORM_hid_get_serial_number_string,
(void *)PLATFORM_hid_get_indexed_string,
(void *)PLATFORM_hid_get_device_info,
(void *)PLATFORM_hid_get_report_descriptor,
(void *)PLATFORM_hid_error
PLATFORM_hid_write_backend,
PLATFORM_hid_read_timeout_backend,
PLATFORM_hid_read_backend,
PLATFORM_hid_set_nonblocking_backend,
PLATFORM_hid_send_feature_report_backend,
PLATFORM_hid_get_feature_report_backend,
PLATFORM_hid_get_input_report_backend,
PLATFORM_hid_close_backend,
PLATFORM_hid_get_manufacturer_string_backend,
PLATFORM_hid_get_product_string_backend,
PLATFORM_hid_get_serial_number_string_backend,
PLATFORM_hid_get_indexed_string_backend,
PLATFORM_hid_get_device_info_backend,
PLATFORM_hid_get_report_descriptor_backend,
PLATFORM_hid_error_backend
};
#endif // HAVE_PLATFORM_BACKEND
#ifdef HAVE_DRIVER_BACKEND
HIDAPI_BACKEND_WRAPPERS(DRIVER, DRIVER_hid_device)
static const struct hidapi_backend DRIVER_Backend = {
(void *)DRIVER_hid_write,
(void *)DRIVER_hid_read_timeout,
(void *)DRIVER_hid_read,
(void *)DRIVER_hid_set_nonblocking,
(void *)DRIVER_hid_send_feature_report,
(void *)DRIVER_hid_get_feature_report,
(void *)DRIVER_hid_get_input_report,
(void *)DRIVER_hid_close,
(void *)DRIVER_hid_get_manufacturer_string,
(void *)DRIVER_hid_get_product_string,
(void *)DRIVER_hid_get_serial_number_string,
(void *)DRIVER_hid_get_indexed_string,
(void *)DRIVER_hid_get_device_info,
(void *)DRIVER_hid_get_report_descriptor,
(void *)DRIVER_hid_error
DRIVER_hid_write_backend,
DRIVER_hid_read_timeout_backend,
DRIVER_hid_read_backend,
DRIVER_hid_set_nonblocking_backend,
DRIVER_hid_send_feature_report_backend,
DRIVER_hid_get_feature_report_backend,
DRIVER_hid_get_input_report_backend,
DRIVER_hid_close_backend,
DRIVER_hid_get_manufacturer_string_backend,
DRIVER_hid_get_product_string_backend,
DRIVER_hid_get_serial_number_string_backend,
DRIVER_hid_get_indexed_string_backend,
DRIVER_hid_get_device_info_backend,
DRIVER_hid_get_report_descriptor_backend,
DRIVER_hid_error_backend
};
#endif // HAVE_DRIVER_BACKEND
#ifdef HAVE_LIBUSB
HIDAPI_BACKEND_WRAPPERS(LIBUSB, LIBUSB_hid_device)
static const struct hidapi_backend LIBUSB_Backend = {
(void *)LIBUSB_hid_write,
(void *)LIBUSB_hid_read_timeout,
(void *)LIBUSB_hid_read,
(void *)LIBUSB_hid_set_nonblocking,
(void *)LIBUSB_hid_send_feature_report,
(void *)LIBUSB_hid_get_feature_report,
(void *)LIBUSB_hid_get_input_report,
(void *)LIBUSB_hid_close,
(void *)LIBUSB_hid_get_manufacturer_string,
(void *)LIBUSB_hid_get_product_string,
(void *)LIBUSB_hid_get_serial_number_string,
(void *)LIBUSB_hid_get_indexed_string,
(void *)LIBUSB_hid_get_device_info,
(void *)LIBUSB_hid_get_report_descriptor,
(void *)LIBUSB_hid_error
LIBUSB_hid_write_backend,
LIBUSB_hid_read_timeout_backend,
LIBUSB_hid_read_backend,
LIBUSB_hid_set_nonblocking_backend,
LIBUSB_hid_send_feature_report_backend,
LIBUSB_hid_get_feature_report_backend,
LIBUSB_hid_get_input_report_backend,
LIBUSB_hid_close_backend,
LIBUSB_hid_get_manufacturer_string_backend,
LIBUSB_hid_get_product_string_backend,
LIBUSB_hid_get_serial_number_string_backend,
LIBUSB_hid_get_indexed_string_backend,
LIBUSB_hid_get_device_info_backend,
LIBUSB_hid_get_report_descriptor_backend,
LIBUSB_hid_error_backend
};
#endif // HAVE_LIBUSB
#undef HIDAPI_BACKEND_WRAPPERS
struct SDL_hid_device
{
void *device;