java-topology/defects/sdl/patch/sdl-0001-gamepad-mapping-tail-walk.patch

56 lines
2.4 KiB
Diff

# UNDF: UNDF-2026-000000751
# UNDF: (leave blank)
SDL CWE-407: SDL_PrivateAddMappingForGUID — O(M) tail walk when inserting each mapping → O(M²) bulk load
The s_pSupportedGamepads linked list has no tail pointer. Every new mapping
insertion walks the entire list from head to tail (SDL_gamepad.c:2213-2217)
just to find the insertion point. Loading M mappings therefore costs O(M²).
The SDL_GameControllerDB community database ships >30 000 entries. At M=30 000,
the tail walk alone performs ~450 000 000 pointer dereferences at startup.
Additionally, SDL_PrivateGetGamepadMappingForGUID (called once per insert for
dedup) performs its own O(M) linked-list scan, contributing another O(M²) term.
Severity: MEDIUM — startup latency; proportional to community DB size.
Complexity: O(M²) → O(M) with a tail pointer + hash-table dedup.
--- a/src/joystick/SDL_gamepad.c
+++ b/src/joystick/SDL_gamepad.c
@@ DEFECT sdl-0001: tail walk on s_pSupportedGamepads @@
static SDL_GUID s_zeroGUID;
static GamepadMapping_t *s_pSupportedGamepads SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
+/* FIX sdl-0001: track list tail to avoid O(M) walk on every append */
+static GamepadMapping_t *s_pLastSupportedGamepad SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
static GamepadMapping_t *s_pDefaultMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
@@ SDL_PrivateAddMappingForGUID — replace tail walk with O(1) tail pointer @@
- if (s_pSupportedGamepads) {
- // Add the mapping to the end of the list
- GamepadMapping_t *pCurrMapping, *pPrevMapping;
-
- for (pPrevMapping = s_pSupportedGamepads, pCurrMapping = pPrevMapping->next;
- pCurrMapping;
- pPrevMapping = pCurrMapping, pCurrMapping = pCurrMapping->next) {
- // continue;
- }
- pPrevMapping->next = pGamepadMapping;
- } else {
- s_pSupportedGamepads = pGamepadMapping;
- }
+ /* FIX sdl-0001: O(1) append via tail pointer */
+ if (s_pLastSupportedGamepad) {
+ s_pLastSupportedGamepad->next = pGamepadMapping;
+ } else {
+ s_pSupportedGamepads = pGamepadMapping;
+ }
+ s_pLastSupportedGamepad = pGamepadMapping;
@@ SDL_QuitGamepadMappings (or wherever s_pSupportedGamepads is reset to NULL) @@
- s_pSupportedGamepads = NULL;
+ s_pSupportedGamepads = NULL;
+ s_pLastSupportedGamepad = NULL; /* FIX sdl-0001: reset tail pointer */