From 8708ba7393d80de3bfb108d5a0ba159931b2be1b Mon Sep 17 00:00:00 2001
From: meyraud705 <[EMAIL REDACTED]>
Date: Fri, 10 Nov 2023 13:25:54 +0100
Subject: [PATCH] Don't leak if realloc fails
---
src/joystick/SDL_gamepad.c | 8 ++++++--
src/joystick/windows/SDL_rawinputjoystick.c | 14 ++++++++------
src/thread/SDL_thread.c | 6 ++++--
src/video/kmsdrm/SDL_kmsdrmvideo.c | 11 ++++++-----
src/video/wayland/SDL_waylandmouse.c | 7 ++++---
src/video/wayland/SDL_waylandwindow.c | 9 +++++++--
src/video/x11/SDL_x11window.c | 5 +++--
7 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c
index 7bba99801086..bb7e55c84b97 100644
--- a/src/joystick/SDL_gamepad.c
+++ b/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;
}
diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c
index e9f8636d6c16..67dcb9d7b2ad 100644
--- a/src/joystick/windows/SDL_rawinputjoystick.c
+++ b/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;
diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c
index c03fc41301c2..49f24d47e1d7 100644
--- a/src/thread/SDL_thread.c
+++ b/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;
diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c
index 9aee16dae53c..544cbff07547 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c
+++ b/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;
diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c
index 8895e4cbc739..02d30b25db57 100644
--- a/src/video/wayland/SDL_waylandmouse.c
+++ b/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) {
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index b923c47191f3..d7acd64bac0a 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/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. */
diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c
index 9c2b53e95899..459a55a55fc8 100644
--- a/src/video/x11/SDL_x11window.c
+++ b/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++;