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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c
index 453996c..9d005b0 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 41e5877..e50f208 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 efd475d..54e07e8 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 0b141aa..3acfc47 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;