From a7ae9175c331fd962caf6b6e42dded4a1a186f41 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 16 Dec 2019 10:20:03 -0800 Subject: [PATCH] Fixed bug 4898 - No rumble because of integer overflow in SDL_JoystickRumble meyraud705 On a Dualshock 4 controller using hidapi driver, calling SDL_JoystickRumble with a duration too long (SDL_HAPTIC_INFINITY for example) causes the rumble to stop immediately. This happens because of integer overflow on line 301 of SDL_hidapi_ps4.c (https://hg.libsdl.org/SDL/file/a3077169ad23/src/joystick/hidapi/SDL_hidapi_ps4.c#l301), which sets expiration time in the past. --- src/joystick/hidapi/SDL_hidapi_ps4.c | 2 +- src/joystick/hidapi/SDL_hidapi_xbox360.c | 2 +- src/joystick/hidapi/SDL_hidapi_xboxone.c | 2 +- src/joystick/hidapi/SDL_hidapijoystick_c.h | 3 +++ 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c index 453996c3b55a3..9d005b0631ae3 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -298,7 +298,7 @@ HIDAPI_DriverPS4_Rumble(SDL_Joystick *joystick, hid_device *dev, void *context, } if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) { - ctx->rumble_expiration = SDL_GetTicks() + duration_ms; + ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); } else { ctx->rumble_expiration = 0; } diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360.c b/src/joystick/hidapi/SDL_hidapi_xbox360.c index 41e5877475906..e50f20874d09c 100644 --- a/src/joystick/hidapi/SDL_hidapi_xbox360.c +++ b/src/joystick/hidapi/SDL_hidapi_xbox360.c @@ -381,7 +381,7 @@ HIDAPI_DriverXbox360_Rumble(SDL_Joystick *joystick, hid_device *dev, void *conte #endif /* __WIN32__ */ if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) { - ctx->rumble_expiration = SDL_GetTicks() + duration_ms; + ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); } else { ctx->rumble_expiration = 0; } diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index efd475dbf1d73..54e07e810bb57 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -298,7 +298,7 @@ HIDAPI_DriverXboxOne_Rumble(SDL_Joystick *joystick, hid_device *dev, void *conte } if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) { - ctx->rumble_expiration = SDL_GetTicks() + duration_ms; + ctx->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); } else { ctx->rumble_expiration = 0; } diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index 0b141aaccc038..3acfc47365465 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -43,6 +43,9 @@ #undef SDL_JOYSTICK_HIDAPI_XBOXONE #endif +/* Prevent rumble duration overflow */ +#define SDL_MAX_RUMBLE_DURATION_MS 0x0fffffff + typedef struct _SDL_HIDAPI_DeviceDriver { const char *hint;