From 71e3998d6c0b0742bc0042894ea8327aadae811a Mon Sep 17 00:00:00 2001 From: Erik Soma Date: Tue, 23 Nov 2021 17:56:46 -0500 Subject: [PATCH] Make SDL_VideoInit cleanup when errors occur before video driver creation. --- src/video/SDL_video.c | 49 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index accba175e..ff55308b9 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -465,6 +465,10 @@ SDL_VideoInit(const char *driver_name) SDL_VideoDevice *video; int index; int i; + SDL_bool init_events = SDL_FALSE; + SDL_bool init_keyboard = SDL_FALSE; + SDL_bool init_mouse = SDL_FALSE; + SDL_bool init_touch = SDL_FALSE; /* Check to make sure we don't overwrite '_this' */ if (_this != NULL) { @@ -476,12 +480,22 @@ SDL_VideoInit(const char *driver_name) #endif /* Start the event loop */ - if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0 || - SDL_KeyboardInit() < 0 || - SDL_MouseInit() < 0 || - SDL_TouchInit() < 0) { - return -1; + if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) { + goto pre_driver_error; } + init_events = SDL_TRUE; + if (SDL_KeyboardInit() < 0) { + goto pre_driver_error; + } + init_keyboard = SDL_TRUE; + if (SDL_MouseInit() < 0) { + goto pre_driver_error; + } + init_mouse = SDL_TRUE; + if (SDL_TouchInit() < 0) { + goto pre_driver_error; + } + init_touch = SDL_TRUE; /* Select the proper video driver */ i = index = 0; @@ -516,10 +530,15 @@ SDL_VideoInit(const char *driver_name) } if (video == NULL) { if (driver_name) { - return SDL_SetError("%s not available", driver_name); + SDL_SetError("%s not available", driver_name); + goto pre_driver_error; } - return SDL_SetError("No available video device"); + SDL_SetError("No available video device"); + goto pre_driver_error; } + + /* From this point on, use SDL_VideoQuit to cleanup on error, rather than + pre_driver_error. */ _this = video; _this->name = bootstrap[i]->name; _this->next_object_id = 1; @@ -575,6 +594,22 @@ SDL_VideoInit(const char *driver_name) /* We're ready to go! */ return 0; + +pre_driver_error: + SDL_assert(_this == NULL); + if (init_touch) { + SDL_TouchQuit(); + } + if (init_mouse) { + SDL_MouseQuit(); + } + if (init_keyboard) { + SDL_KeyboardQuit(); + } + if (init_events) { + SDL_QuitSubSystem(SDL_INIT_EVENTS); + } + return -1; } const char *