Procházet zdrojové kódy

Don't leak if realloc fails

meyraud705 před 1 rokem
rodič
revize
8708ba7393

+ 6 - 2
src/joystick/SDL_gamepad.c

@@ -1124,6 +1124,7 @@ static int SDL_PrivateParseGamepadElement(SDL_Gamepad *gamepad, const char *szGa
     SDL_bool invert_input = SDL_FALSE;
     char half_axis_input = 0;
     char half_axis_output = 0;
+    SDL_GamepadBinding *new_bindings;
 
     SDL_AssertJoysticksLocked();
 
@@ -1198,11 +1199,14 @@ static int SDL_PrivateParseGamepadElement(SDL_Gamepad *gamepad, const char *szGa
     }
 
     ++gamepad->num_bindings;
-    gamepad->bindings = (SDL_GamepadBinding *)SDL_realloc(gamepad->bindings, gamepad->num_bindings * sizeof(*gamepad->bindings));
-    if (!gamepad->bindings) {
+    new_bindings = (SDL_GamepadBinding *)SDL_realloc(gamepad->bindings, gamepad->num_bindings * sizeof(*gamepad->bindings));
+    if (!new_bindings) {
+        SDL_free(gamepad->bindings);
         gamepad->num_bindings = 0;
+        gamepad->bindings = NULL;
         return SDL_OutOfMemory();
     }
+    gamepad->bindings = new_bindings;
     gamepad->bindings[gamepad->num_bindings - 1] = bind;
     return 0;
 }

+ 8 - 6
src/joystick/windows/SDL_rawinputjoystick.c

@@ -615,16 +615,18 @@ static int RAWINPUT_UpdateWindowsGamingInput()
                         if (!found) {
                             /* New device, add it */
                             WindowsGamingInputGamepadState *gamepad_state;
-
-                            wgi_state.per_gamepad_count++;
-                            wgi_state.per_gamepad = SDL_realloc(wgi_state.per_gamepad, sizeof(wgi_state.per_gamepad[0]) * wgi_state.per_gamepad_count);
-                            if (!wgi_state.per_gamepad) {
-                                return SDL_OutOfMemory();
-                            }
+                            WindowsGamingInputGamepadState **new_per_gamepad;
                             gamepad_state = SDL_calloc(1, sizeof(*gamepad_state));
                             if (!gamepad_state) {
                                 return SDL_OutOfMemory();
                             }
+                            new_per_gamepad = SDL_realloc(wgi_state.per_gamepad, sizeof(wgi_state.per_gamepad[0]) * (wgi_state.per_gamepad_count + 1));
+                            if (!new_per_gamepad) {
+                                SDL_free(gamepad_state);
+                                return SDL_OutOfMemory();
+                            }
+                            wgi_state.per_gamepad = new_per_gamepad;
+                            wgi_state.per_gamepad_count++;
                             wgi_state.per_gamepad[wgi_state.per_gamepad_count - 1] = gamepad_state;
                             gamepad_state->gamepad = gamepad;
                             gamepad_state->connected = SDL_TRUE;

+ 4 - 2
src/thread/SDL_thread.c

@@ -54,13 +54,15 @@ int SDL_SetTLS(SDL_TLSID id, const void *value, void(SDLCALL *destructor)(void *
     storage = SDL_SYS_GetTLSData();
     if (!storage || (id > storage->limit)) {
         unsigned int i, oldlimit, newlimit;
+        SDL_TLSData *new_storage;
 
         oldlimit = storage ? storage->limit : 0;
         newlimit = (id + TLS_ALLOC_CHUNKSIZE);
-        storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage) + (newlimit - 1) * sizeof(storage->array[0]));
-        if (!storage) {
+        new_storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage) + (newlimit - 1) * sizeof(storage->array[0]));
+        if (!new_storage) {
             return SDL_OutOfMemory();
         }
+        storage = new_storage;
         storage->limit = newlimit;
         for (i = oldlimit; i < newlimit; ++i) {
             storage->array[i].data = NULL;

+ 6 - 5
src/video/kmsdrm/SDL_kmsdrmvideo.c

@@ -1555,13 +1555,14 @@ int KMSDRM_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
        extra window as a dummy surface when working with multiple contexts */
     if (viddata->num_windows >= viddata->max_windows) {
         unsigned int new_max_windows = viddata->max_windows + 1;
-        viddata->windows = (SDL_Window **)SDL_realloc(viddata->windows,
-                                                      new_max_windows * sizeof(SDL_Window *));
-        viddata->max_windows = new_max_windows;
-
-        if (!viddata->windows) {
+        SDL_Window **new_windows = (SDL_Window **)SDL_realloc(viddata->windows,
+                                                              new_max_windows * sizeof(SDL_Window *));
+        if (!new_windows) {
             return SDL_OutOfMemory();
         }
+        viddata->windows = new_windows;
+        viddata->max_windows = new_max_windows;
+
     }
 
     viddata->windows[viddata->num_windows++] = window;

+ 4 - 3
src/video/wayland/SDL_waylandmouse.c

@@ -297,12 +297,13 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa
     if (!theme) {
         const char *xcursor_theme = dbus_cursor_theme;
 
-        vdata->cursor_themes = SDL_realloc(vdata->cursor_themes,
-                                           sizeof(SDL_WaylandCursorTheme) * (vdata->num_cursor_themes + 1));
-        if (!vdata->cursor_themes) {
+        SDL_WaylandCursorTheme *new_cursor_themes = SDL_realloc(vdata->cursor_themes,
+                                                                sizeof(SDL_WaylandCursorTheme) * (vdata->num_cursor_themes + 1));
+        if (!new_cursor_themes) {
             SDL_OutOfMemory();
             return SDL_FALSE;
         }
+        vdata->cursor_themes = new_cursor_themes;
 
         /* Fallback envvar if the DBus properties don't exist */
         if (!xcursor_theme) {

+ 7 - 2
src/video/wayland/SDL_waylandwindow.c

@@ -1196,13 +1196,18 @@ static void handle_surface_enter(void *data, struct wl_surface *surface,
 {
     SDL_WindowData *window = data;
     SDL_DisplayData *driverdata = wl_output_get_user_data(output);
+    SDL_DisplayData **new_outputs;
 
     if (!SDL_WAYLAND_own_output(output) || !SDL_WAYLAND_own_surface(surface)) {
         return;
     }
 
-    window->outputs = SDL_realloc(window->outputs,
-                                  sizeof(SDL_DisplayData *) * (window->num_outputs + 1));
+    new_outputs = SDL_realloc(window->outputs,
+                              sizeof(SDL_DisplayData *) * (window->num_outputs + 1));
+    if (!new_outputs) {
+        return;
+    }
+    window->outputs = new_outputs;
     window->outputs[window->num_outputs++] = driverdata;
 
     /* Update the scale factor after the move so that fullscreen outputs are updated. */

+ 3 - 2
src/video/x11/SDL_x11window.c

@@ -329,11 +329,12 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, Window w,
         windowlist[numwindows] = data;
         videodata->numwindows++;
     } else {
-        windowlist = (SDL_WindowData **)SDL_realloc(windowlist, (numwindows + 1) * sizeof(*windowlist));
-        if (!windowlist) {
+        SDL_WindowData ** new_windowlist = (SDL_WindowData **)SDL_realloc(windowlist, (numwindows + 1) * sizeof(*windowlist));
+        if (!new_windowlist) {
             SDL_free(data);
             return SDL_OutOfMemory();
         }
+        windowlist = new_windowlist;
         windowlist[numwindows] = data;
         videodata->numwindows++;
         videodata->windowlistlength++;