From 7eb260563064c88f11846b4707f188d8a35e2a56 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 27 Jul 2024 13:36:12 -0700 Subject: [PATCH] Fixed memory leak when a renderer fails to be created The supported texture formats were leaking. In order to catch future issues, we'll just do a full teardown of the renderer in the failure case, and make sure it's safe to do so with a partially initialized renderer. --- src/render/SDL_render.c | 44 +++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 28a0340b46..b3b31e2cf6 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -1144,10 +1144,7 @@ error: #endif if (renderer) { - SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_FALSE); - - SDL_free(renderer->texture_formats); - SDL_free(renderer); + SDL_DestroyRenderer(renderer); } return NULL; @@ -5059,10 +5056,15 @@ void SDL_DestroyRendererWithoutFreeing(SDL_Renderer *renderer) renderer->destroyed = SDL_TRUE; - SDL_DestroyProperties(renderer->props); - SDL_DelEventWatch(SDL_RendererEventWatch, renderer); + if (renderer->window) { + SDL_PropertiesID props = SDL_GetWindowProperties(renderer->window); + if (SDL_GetPointerProperty(props, SDL_PROP_WINDOW_RENDERER_POINTER, NULL) == renderer) { + SDL_ClearProperty(props, SDL_PROP_WINDOW_RENDERER_POINTER); + } + } + SDL_DiscardAllCommands(renderer); /* Free existing textures for this renderer */ @@ -5072,18 +5074,27 @@ void SDL_DestroyRendererWithoutFreeing(SDL_Renderer *renderer) SDL_assert(tex != renderer->textures); /* satisfy static analysis. */ } - SDL_free(renderer->vertex_data); - - if (renderer->window) { - SDL_ClearProperty(SDL_GetWindowProperties(renderer->window), SDL_PROP_WINDOW_RENDERER_POINTER); + /* Clean up renderer-specific resources */ + if (renderer->DestroyRenderer) { + renderer->DestroyRenderer(renderer); } - /* Free the target mutex */ - SDL_DestroyMutex(renderer->target_mutex); - renderer->target_mutex = NULL; - - /* Clean up renderer-specific resources */ - renderer->DestroyRenderer(renderer); + if (renderer->target_mutex) { + SDL_DestroyMutex(renderer->target_mutex); + renderer->target_mutex = NULL; + } + if (renderer->vertex_data) { + SDL_free(renderer->vertex_data); + renderer->vertex_data = NULL; + } + if (renderer->texture_formats) { + SDL_free(renderer->texture_formats); + renderer->texture_formats = NULL; + } + if (renderer->props) { + SDL_DestroyProperties(renderer->props); + renderer->props = 0; + } } void SDL_DestroyRenderer(SDL_Renderer *renderer) @@ -5114,7 +5125,6 @@ void SDL_DestroyRenderer(SDL_Renderer *renderer) SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_FALSE); // It's no longer magical... - SDL_free(renderer->texture_formats); SDL_free(renderer); }