diff options
| -rw-r--r-- | src/platform/wayland/ime.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/platform/wayland/ime.c b/src/platform/wayland/ime.c index f326fa8..9f1b27d 100644 --- a/src/platform/wayland/ime.c +++ b/src/platform/wayland/ime.c @@ -87,6 +87,20 @@ static void text_input_leave(void *data, struct zwp_text_input_v3 *text_input, ime_reset(w); } +/* Copy protocol text, which libwayland always NUL-terminates, up to + * IME_TEXT_MAX bytes. Measuring with strlen keeps GCC from flagging a + * bounded read past a short caller buffer. */ +static char *copy_text(const char *text) +{ + size_t len = strlen(text); + if (len > IME_TEXT_MAX) len = IME_TEXT_MAX; + char *copy = malloc(len + 1); + if (!copy) return NULL; + memcpy(copy, text, len); + copy[len] = '\0'; + return copy; +} + static void text_input_preedit_string(void *data, struct zwp_text_input_v3 *text_input, const char *text, int32_t cursor_begin, int32_t cursor_end) @@ -96,7 +110,7 @@ static void text_input_preedit_string(void *data, if (!w) return; keyboard_text_reset((struct seat *)data); free(w->ime_preedit); - w->ime_preedit = text ? strndup(text, IME_TEXT_MAX) : NULL; + w->ime_preedit = text ? copy_text(text) : NULL; int len = w->ime_preedit ? (int)strlen(w->ime_preedit) : 0; bool shown = cursor_begin >= 0 && cursor_end >= cursor_begin && cursor_end <= len; @@ -112,7 +126,7 @@ static void text_input_commit_string(void *data, if (!w) return; keyboard_text_reset((struct seat *)data); free(w->ime_commit); - w->ime_commit = (text && text[0]) ? strndup(text, IME_TEXT_MAX) : NULL; + w->ime_commit = (text && text[0]) ? copy_text(text) : NULL; } static void text_input_delete_surrounding_text(void *data, |
