From 18463ccb8f58e003910f7dec797c9da451321809 Mon Sep 17 00:00:00 2001 From: foxtacles Date: Fri, 3 Apr 2026 15:07:50 -0700 Subject: [PATCH] (emscripten) Add null checks for gamepad in vendor/product/xinput helpers (#15313) navigator.getGamepads() can return null for a slot if the gamepad disconnects between the gamepadconnected event and the proxied MAIN_THREAD_EM_ASM_INT call. This causes a TypeError when accessing gamepad.id. Add null guards matching the pattern already used in EMSCRIPTEN_JoystickOpen and EMSCRIPTEN_JoystickRumble. (cherry picked from commit 59602fb4732c8ab6f3e0a9d94d7fb8e34f1f79f8) --- src/joystick/emscripten/SDL_sysjoystick.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index 156917e682..5d831bddbb 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -37,9 +37,11 @@ static int numjoysticks = 0; static int SDL_GetEmscriptenJoystickVendor(int device_index) { - // Let's assume that if we're calling these function then the gamepad object definitely exists return MAIN_THREAD_EM_ASM_INT({ let gamepad = navigator['getGamepads']()[$0]; + if (!gamepad) { + return 0; + } // Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc) let vendor_str = 'Vendor: '; @@ -62,6 +64,9 @@ static int SDL_GetEmscriptenJoystickProduct(int device_index) { return MAIN_THREAD_EM_ASM_INT({ let gamepad = navigator['getGamepads']()[$0]; + if (!gamepad) { + return 0; + } // Chrome, Edge, Opera: Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc) let product_str = 'Product: '; @@ -84,6 +89,9 @@ static int SDL_IsEmscriptenJoystickXInput(int device_index) { return MAIN_THREAD_EM_ASM_INT({ let gamepad = navigator['getGamepads']()[$0]; + if (!gamepad) { + return 0; + } // Chrome, Edge, Opera: Xbox 360 Controller (XInput STANDARD GAMEPAD) // Firefox: xinput