Kaynağa Gözat

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.
Sam Lantinga 5 yıl önce
ebeveyn
işleme
a7ae9175c3

+ 1 - 1
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;
     }

+ 1 - 1
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;
     }

+ 1 - 1
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;
     }

+ 3 - 0
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;