Преглед на файлове

mouse: Fix memory leak if events are sent after shutdown

Only allocate memory for source events if the mouse system is in the initialized state, otherwise, spurious events during shutdown can cause a leak.
Frank Praznik преди 3 седмици
родител
ревизия
d058781f71
променени са 1 файла, в които са добавени 32 реда и са изтрити 30 реда
  1. 32 30
      src/events/SDL_mouse.c

+ 32 - 30
src/events/SDL_mouse.c

@@ -39,7 +39,7 @@ static SDL_Mouse SDL_mouse;
 static int SDL_mouse_count;
 static SDL_MouseID *SDL_mice;
 static SDL_HashTable *SDL_mouse_names;
-static bool SDL_mouse_quitting;
+static bool SDL_mouse_initialized;
 
 // for mapping mouse events to touch
 static bool track_mouse_down = false;
@@ -250,6 +250,8 @@ bool SDL_PreInitMouse(void)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
 
+    SDL_mouse_initialized = true;
+
     SDL_zerop(mouse);
 
     SDL_AddHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME,
@@ -401,7 +403,7 @@ void SDL_RemoveMouse(SDL_MouseID mouseID)
         }
     }
 
-    if (!SDL_mouse_quitting) {
+    if (SDL_mouse_initialized) {
         SDL_Event event;
         SDL_zero(event);
         event.type = SDL_EVENT_MOUSE_REMOVED;
@@ -846,38 +848,40 @@ static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID m
     SDL_MouseInputSource *source, *match = NULL, *sources;
     int i;
 
-    for (i = 0; i < mouse->num_sources; ++i) {
-        source = &mouse->sources[i];
-        if (source->mouseID == mouseID) {
-            match = source;
-            break;
-        }
-    }
-
-    if (!down && (!match || !(match->buttonstate & SDL_BUTTON_MASK(button)))) {
-        /* This might be a button release from a transition between mouse messages and raw input.
-         * See if there's another mouse source that already has that button down and use that.
-         */
+    if (SDL_mouse_initialized) {
         for (i = 0; i < mouse->num_sources; ++i) {
             source = &mouse->sources[i];
-            if ((source->buttonstate & SDL_BUTTON_MASK(button))) {
+            if (source->mouseID == mouseID) {
                 match = source;
                 break;
             }
         }
-    }
-    if (match) {
-        return match;
-    }
 
-    sources = (SDL_MouseInputSource *)SDL_realloc(mouse->sources, (mouse->num_sources + 1) * sizeof(*mouse->sources));
-    if (sources) {
-        mouse->sources = sources;
-        ++mouse->num_sources;
-        source = &sources[mouse->num_sources - 1];
-        SDL_zerop(source);
-        source->mouseID = mouseID;
-        return source;
+        if (!down && (!match || !(match->buttonstate & SDL_BUTTON_MASK(button)))) {
+            /* This might be a button release from a transition between mouse messages and raw input.
+             * See if there's another mouse source that already has that button down and use that.
+             */
+            for (i = 0; i < mouse->num_sources; ++i) {
+                source = &mouse->sources[i];
+                if ((source->buttonstate & SDL_BUTTON_MASK(button))) {
+                    match = source;
+                    break;
+                }
+            }
+        }
+        if (match) {
+            return match;
+        }
+
+        sources = (SDL_MouseInputSource *)SDL_realloc(mouse->sources, (mouse->num_sources + 1) * sizeof(*mouse->sources));
+        if (sources) {
+            mouse->sources = sources;
+            ++mouse->num_sources;
+            source = &sources[mouse->num_sources - 1];
+            SDL_zerop(source);
+            source->mouseID = mouseID;
+            return source;
+        }
     }
     return NULL;
 }
@@ -1080,7 +1084,7 @@ void SDL_QuitMouse(void)
     SDL_Cursor *cursor, *next;
     SDL_Mouse *mouse = SDL_GetMouse();
 
-    SDL_mouse_quitting = true;
+    SDL_mouse_initialized = false;
 
     if (mouse->added_mouse_touch_device) {
         SDL_DelTouch(SDL_MOUSE_TOUCHID);
@@ -1181,8 +1185,6 @@ void SDL_QuitMouse(void)
         mouse->internal = NULL;
     }
     SDL_zerop(mouse);
-
-    SDL_mouse_quitting = false;
 }
 
 bool SDL_SetRelativeMouseTransform(SDL_MouseMotionTransformCallback transform, void *userdata)