From be203832408da8076da555cab8e9f4690a6da2ff Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Mon, 10 Aug 2020 09:24:22 +0200 Subject: [PATCH] verbatim: report and ignore an invalid keystroke for Unicode input When Unicode Input has started (by typing 0 or 1 at the Verbatim Input "prompt"), and something is typed that is not a hexadecimal digit, then don't try to enter this character into the buffer but simply report it as invalid and ignore it. Because most likely the user mistyped and actually meant to enter a valid hex digit. This fixes https://savannah.gnu.org/bugs/?58927. The bug was old -- it existed since at least version 2.0.6. --- src/winio.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/winio.c b/src/winio.c index 3a6009c8..e4095cc0 100644 --- a/src/winio.c +++ b/src/winio.c @@ -1278,6 +1278,8 @@ int get_kbinput(WINDOW *win, bool showcursor) } #ifdef ENABLE_UTF8 +#define INVALID_DIGIT -77 + /* If the given symbol is a valid hexadecimal digit, multiply it by factor * and add the result to the given unicode, and return PROCEED to signify * okay. When not a hexadecimal digit, return the symbol itself. */ @@ -1288,7 +1290,7 @@ long add_unicode_digit(int symbol, long factor, long *unicode) else if ('a' <= tolower(symbol) && tolower(symbol) <= 'f') *unicode += (tolower(symbol) - 'a' + 10) * factor; else - return (long)symbol; + return INVALID_DIGIT; return PROCEED; } @@ -1312,7 +1314,7 @@ long assemble_unicode(int symbol) if (symbol == '0' || unicode == 0) retval = add_unicode_digit(symbol, 0x10000, &unicode); else - retval = symbol; + retval = INVALID_DIGIT; break; case 3: /* Later digits may be any hexadecimal value. */ @@ -1395,6 +1397,11 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *count) unicode = assemble_unicode(keycode); } + /* For an invalid digit, discard its possible continuation bytes. */ + if (unicode == INVALID_DIGIT) + while (key_buffer_len > 0 && 0x7F < *key_buffer && *key_buffer < 0xC0) + get_input(NULL); + /* Convert the Unicode value to a multibyte sequence. */ multibyte = make_mbchar(unicode, (int *)count);