From f6363fde9aae6abbaa3583eb0273f716e96a7811 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 5 Apr 2023 11:23:28 -0700 Subject: [PATCH] Fixed crash if joystick->hwdata != NULL && device->driver == NULL This should never happen, but we're seeing it in the wild, so make sure that we can never call into a NULL device driver. (cherry picked from commit e13b74ccf0b20a20bd4baf1617bdc4f84c13feb7) --- src/joystick/hidapi/SDL_hidapijoystick.c | 55 +++++++++++------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index fcbfaa44a..d66028d96 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -1432,15 +1432,25 @@ static int HIDAPI_JoystickOpen(SDL_Joystick *joystick, int device_index) return 0; } +static SDL_bool HIDAPI_GetJoystickDevice(SDL_Joystick *joystick, SDL_HIDAPI_Device **device) +{ + SDL_AssertJoysticksLocked(); + + if (joystick && joystick->hwdata) { + *device = joystick->hwdata->device; + if (*device && (*device)->driver) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + static int HIDAPI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { int result; + SDL_HIDAPI_Device *device = NULL; - SDL_AssertJoysticksLocked(); - - if (joystick->hwdata) { - SDL_HIDAPI_Device *device = joystick->hwdata->device; - + if (HIDAPI_GetJoystickDevice(joystick, &device)) { result = device->driver->RumbleJoystick(device, joystick, low_frequency_rumble, high_frequency_rumble); } else { result = SDL_SetError("Rumble failed, device disconnected"); @@ -1452,12 +1462,9 @@ static int HIDAPI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_ru static int HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { int result; + SDL_HIDAPI_Device *device = NULL; - SDL_AssertJoysticksLocked(); - - if (joystick->hwdata) { - SDL_HIDAPI_Device *device = joystick->hwdata->device; - + if (HIDAPI_GetJoystickDevice(joystick, &device)) { result = device->driver->RumbleJoystickTriggers(device, joystick, left_rumble, right_rumble); } else { result = SDL_SetError("Rumble failed, device disconnected"); @@ -1469,12 +1476,9 @@ static int HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rum static Uint32 HIDAPI_JoystickGetCapabilities(SDL_Joystick *joystick) { Uint32 result = 0; + SDL_HIDAPI_Device *device = NULL; - SDL_AssertJoysticksLocked(); - - if (joystick->hwdata) { - SDL_HIDAPI_Device *device = joystick->hwdata->device; - + if (HIDAPI_GetJoystickDevice(joystick, &device)) { result = device->driver->GetJoystickCapabilities(device, joystick); } @@ -1484,12 +1488,9 @@ static Uint32 HIDAPI_JoystickGetCapabilities(SDL_Joystick *joystick) static int HIDAPI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) { int result; + SDL_HIDAPI_Device *device = NULL; - SDL_AssertJoysticksLocked(); - - if (joystick->hwdata) { - SDL_HIDAPI_Device *device = joystick->hwdata->device; - + if (HIDAPI_GetJoystickDevice(joystick, &device)) { result = device->driver->SetJoystickLED(device, joystick, red, green, blue); } else { result = SDL_SetError("SetLED failed, device disconnected"); @@ -1501,12 +1502,9 @@ static int HIDAPI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, static int HIDAPI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) { int result; + SDL_HIDAPI_Device *device = NULL; - SDL_AssertJoysticksLocked(); - - if (joystick->hwdata) { - SDL_HIDAPI_Device *device = joystick->hwdata->device; - + if (HIDAPI_GetJoystickDevice(joystick, &device)) { result = device->driver->SendJoystickEffect(device, joystick, data, size); } else { result = SDL_SetError("SendEffect failed, device disconnected"); @@ -1518,12 +1516,9 @@ static int HIDAPI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, i static int HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { int result; + SDL_HIDAPI_Device *device = NULL; - SDL_AssertJoysticksLocked(); - - if (joystick->hwdata) { - SDL_HIDAPI_Device *device = joystick->hwdata->device; - + if (HIDAPI_GetJoystickDevice(joystick, &device)) { result = device->driver->SetJoystickSensorsEnabled(device, joystick, enabled); } else { result = SDL_SetError("SetSensorsEnabled failed, device disconnected");