From cae2a28f5b470fc56de14c71a7edcddae101312d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 27 Jan 2026 11:25:38 -0800 Subject: [PATCH] Fixed unaligned access in NVIDIA SHIELD Controller driver Also refactored the LOAD16() and LOAD32() macros into SDL_hidapijoystick_c.h --- src/joystick/hidapi/SDL_hidapi_flydigi.c | 2 -- src/joystick/hidapi/SDL_hidapi_ps3.c | 2 -- src/joystick/hidapi/SDL_hidapi_ps4.c | 6 ---- src/joystick/hidapi/SDL_hidapi_ps5.c | 6 ---- src/joystick/hidapi/SDL_hidapi_shield.c | 38 ++++++++++++++------- src/joystick/hidapi/SDL_hidapi_steam_hori.c | 2 -- src/joystick/hidapi/SDL_hidapi_xboxone.c | 2 -- src/joystick/hidapi/SDL_hidapijoystick_c.h | 6 ++++ 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_flydigi.c b/src/joystick/hidapi/SDL_hidapi_flydigi.c index 3979861733..96b8b967cb 100644 --- a/src/joystick/hidapi/SDL_hidapi_flydigi.c +++ b/src/joystick/hidapi/SDL_hidapi_flydigi.c @@ -80,8 +80,6 @@ enum #define FLYDIGI_V2_ACQUIRE_CONTROLLER_COMMAND 0x1C #define FLYDIGI_V2_INPUT_REPORT 0xEF -#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) - typedef struct { SDL_HIDAPI_Device *device; diff --git a/src/joystick/hidapi/SDL_hidapi_ps3.c b/src/joystick/hidapi/SDL_hidapi_ps3.c index 95f6d99880..ede49cbaa7 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps3.c +++ b/src/joystick/hidapi/SDL_hidapi_ps3.c @@ -32,8 +32,6 @@ // Define this if you want to log all packets from the controller // #define DEBUG_PS3_PROTOCOL -#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) - typedef enum { k_EPS3ReportIdState = 1, diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c index de2c047ad7..3f57a6d30f 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -44,12 +44,6 @@ #define BLUETOOTH_DISCONNECT_TIMEOUT_MS 500 -#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) -#define LOAD32(A, B, C, D) ((((Uint32)(A)) << 0) | \ - (((Uint32)(B)) << 8) | \ - (((Uint32)(C)) << 16) | \ - (((Uint32)(D)) << 24)) - enum { SDL_GAMEPAD_BUTTON_PS4_TOUCHPAD = 11 diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c index 526d6a3706..133db1a137 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps5.c +++ b/src/joystick/hidapi/SDL_hidapi_ps5.c @@ -43,12 +43,6 @@ #define ACCEL_RES_PER_G 8192.0f #define BLUETOOTH_DISCONNECT_TIMEOUT_MS 500 -#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) -#define LOAD32(A, B, C, D) ((((Uint32)(A)) << 0) | \ - (((Uint32)(B)) << 8) | \ - (((Uint32)(C)) << 16) | \ - (((Uint32)(D)) << 24)) - enum { SDL_GAMEPAD_BUTTON_PS5_TOUCHPAD = 11, diff --git a/src/joystick/hidapi/SDL_hidapi_shield.c b/src/joystick/hidapi/SDL_hidapi_shield.c index e6a25d5c71..a057a04865 100644 --- a/src/joystick/hidapi/SDL_hidapi_shield.c +++ b/src/joystick/hidapi/SDL_hidapi_shield.c @@ -289,6 +289,7 @@ static bool HIDAPI_DriverShield_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *dev static void HIDAPI_DriverShield_HandleStatePacketV103(SDL_Joystick *joystick, SDL_DriverShield_Context *ctx, Uint8 *data, int size) { Uint64 timestamp = SDL_GetTicksNS(); + Sint16 axis; if (ctx->last_state[3] != data[3]) { Uint8 hat; @@ -346,14 +347,20 @@ static void HIDAPI_DriverShield_HandleStatePacketV103(SDL_Joystick *joystick, SD SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_GUIDE, ((data[2] & 0x80) != 0)); } - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, SDL_Swap16LE(*(Sint16 *)&data[4]) - 0x8000); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, SDL_Swap16LE(*(Sint16 *)&data[6]) - 0x8000); + axis = LOAD16(data[4], data[5]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, axis); + axis = LOAD16(data[6], data[7]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, axis); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, SDL_Swap16LE(*(Sint16 *)&data[8]) - 0x8000); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, SDL_Swap16LE(*(Sint16 *)&data[10]) - 0x8000); + axis = LOAD16(data[8], data[9]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, axis); + axis = LOAD16(data[10], data[11]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, axis); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, SDL_Swap16LE(*(Sint16 *)&data[12]) - 0x8000); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, SDL_Swap16LE(*(Sint16 *)&data[14]) - 0x8000); + axis = LOAD16(data[12], data[13]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis); + axis = LOAD16(data[14], data[15]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, axis); SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); } @@ -379,6 +386,7 @@ static void HIDAPI_DriverShield_HandleTouchPacketV103(SDL_Joystick *joystick, SD static void HIDAPI_DriverShield_HandleStatePacketV104(SDL_Joystick *joystick, SDL_DriverShield_Context *ctx, Uint8 *data, int size) { Uint64 timestamp = SDL_GetTicksNS(); + Sint16 axis; if (size < 23) { return; @@ -434,14 +442,20 @@ static void HIDAPI_DriverShield_HandleStatePacketV104(SDL_Joystick *joystick, SD SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_START, ((data[4] & 0x01) != 0)); } - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, SDL_Swap16LE(*(Sint16 *)&data[9]) - 0x8000); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, SDL_Swap16LE(*(Sint16 *)&data[11]) - 0x8000); + axis = LOAD16(data[9], data[10]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTX, axis); + axis = LOAD16(data[11], data[12]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFTY, axis); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, SDL_Swap16LE(*(Sint16 *)&data[13]) - 0x8000); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, SDL_Swap16LE(*(Sint16 *)&data[15]) - 0x8000); + axis = LOAD16(data[13], data[14]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTX, axis); + axis = LOAD16(data[15], data[16]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, axis); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, SDL_Swap16LE(*(Sint16 *)&data[19]) - 0x8000); - SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, SDL_Swap16LE(*(Sint16 *)&data[21]) - 0x8000); + axis = LOAD16(data[19], data[20]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_LEFT_TRIGGER, axis); + axis = LOAD16(data[21], data[22]) - 0x8000; + SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER, axis); if (ctx->last_state[17] != data[17]) { //SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SHIELD_SHARE, ((data[17] & 0x01) != 0)); diff --git a/src/joystick/hidapi/SDL_hidapi_steam_hori.c b/src/joystick/hidapi/SDL_hidapi_steam_hori.c index d92634d54a..8d445c9791 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam_hori.c +++ b/src/joystick/hidapi/SDL_hidapi_steam_hori.c @@ -32,8 +32,6 @@ /* Define this if you want to log all packets from the controller */ /*#define DEBUG_HORI_PROTOCOL*/ -#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) - enum { SDL_GAMEPAD_BUTTON_HORI_QAM = 11, diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index 6f7e57e2c3..11e7f574ce 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -52,8 +52,6 @@ #define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689 #define XINPUT_GAMEPAD_TRIGGER_THRESHOLD -25058 // Uint8 30 scaled to Sint16 full range -#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) - enum { SDL_GAMEPAD_BUTTON_XBOX_SHARE_BUTTON = 11 diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index 857b466980..6129441881 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -176,6 +176,12 @@ extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverFlydigi; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSInput; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverZUIKI; +#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) +#define LOAD32(A, B, C, D) ((((Uint32)(A)) << 0) | \ + (((Uint32)(B)) << 8) | \ + (((Uint32)(C)) << 16) | \ + (((Uint32)(D)) << 24)) + // Return true if a HID device is present and supported as a joystick of the given type extern bool HIDAPI_IsDeviceTypePresent(SDL_GamepadType type);