Dynamically allocate long text for SDL_EVENT_TEXT_INPUT events

This prevents input text from being split across Unicode combining or modifier characters, and in practice allocations will rarely happen.
This commit is contained in:
Sam Lantinga
2023-11-04 16:53:25 -07:00
parent 2a1660ab51
commit 75ea3a8d32
8 changed files with 25 additions and 12 deletions

View File

@@ -470,11 +470,13 @@ static void SDL_LogEvent(const SDL_Event *event)
static void SDL_CopyEvent(SDL_Event *dst, SDL_Event *src)
{
*dst = *src;
SDL_copyp(dst, src);
/* Pointers to internal static data must be updated when copying. */
if (src->type == SDL_EVENT_TEXT_EDITING && src->edit.text == src->edit.short_text) {
dst->edit.text = dst->edit.short_text;
} else if (src->type == SDL_EVENT_TEXT_INPUT && src->text.text == src->text.short_text) {
dst->text.text = dst->text.short_text;
} else if (src->type == SDL_EVENT_DROP_TEXT && src->drop.data == src->drop.short_data) {
dst->drop.data = dst->drop.short_data;
}
@@ -1106,6 +1108,12 @@ void SDL_CleanupEvent(SDL_Event *event)
event->edit.text = NULL;
}
break;
case SDL_EVENT_TEXT_INPUT:
if (event->text.text && event->text.text != event->text.short_text) {
SDL_free(event->text.text);
event->text.text = NULL;
}
break;
default:
break;
}

View File

@@ -1071,19 +1071,19 @@ int SDL_SendKeyboardText(const char *text)
posted = 0;
if (SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) {
SDL_Event event;
size_t pos = 0, advance, length = SDL_strlen(text);
event.type = SDL_EVENT_TEXT_INPUT;
event.common.timestamp = 0;
event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
while (pos < length) {
advance = SDL_utf8strlcpy(event.text.text, text + pos, SDL_arraysize(event.text.text));
if (!advance) {
break;
}
pos += advance;
posted |= (SDL_PushEvent(&event) > 0);
size_t len = SDL_strlen(text);
if (len < sizeof(event.text.short_text)) {
SDL_memcpy(event.text.short_text, text, len + 1);
event.text.text = event.text.short_text;
} else {
event.text.text = SDL_strdup(text);
}
posted = (SDL_PushEvent(&event) > 0);
}
return posted;
}