messagebox: Copy title and message up front, to protect SDL_GetError() strings.

It's possible (likely!) someone could just pass a pointer returned by
SDL_GetError for one of these strings, but the message box code has to do a
ton of complicated stuff that might _also_ call SDL_SetError, so you could
end up with the string having different contents by the time you display it.

Just make a copy of the strings unconditionally at the start, so they're safe
no matter where they came from.

Fixes #10932.
This commit is contained in:
Ryan C. Gordon
2024-12-16 18:02:37 -05:00
parent a92eade183
commit d0d1414836

View File

@@ -5455,6 +5455,30 @@ bool SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
return SDL_SetError("Invalid number of buttons");
}
// in case either the title or message was a pointer from SDL_GetError(), make a copy
// now, as we'll likely overwrite error state in here.
bool titleisstack = false, msgisstack = false;
char *titlecpy = NULL;
char *msgcpy = NULL;
if (messageboxdata->title) {
const size_t slen = SDL_strlen(messageboxdata->title) + 1;
titlecpy = SDL_small_alloc(char, slen, &titleisstack);
if (!titlecpy) {
return false;
}
SDL_strlcpy(titlecpy, messageboxdata->title, slen);
}
if (messageboxdata->message) {
const size_t slen = SDL_strlen(messageboxdata->message) + 1;
msgcpy = SDL_small_alloc(char, slen, &msgisstack);
if (!msgcpy) {
SDL_small_free(titlecpy, titleisstack);
return false;
}
SDL_strlcpy(msgcpy, messageboxdata->message, slen);
}
(void)SDL_AtomicIncRef(&SDL_messagebox_count);
current_window = SDL_GetKeyboardFocus();
@@ -5469,9 +5493,11 @@ bool SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
}
SDL_memcpy(&mbdata, messageboxdata, sizeof(*messageboxdata));
mbdata.title = titlecpy;
if (!mbdata.title) {
mbdata.title = "";
}
mbdata.message = msgcpy;
if (!mbdata.message) {
mbdata.message = "";
}
@@ -5534,6 +5560,9 @@ bool SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
SDL_UpdateRelativeMouseMode();
SDL_UpdateMouseCapture(false);
SDL_small_free(msgcpy, msgisstack);
SDL_small_free(titlecpy, titleisstack);
return result;
}