From 3016fbc40b3ca9547ff2a44434fc22407d20340c Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Tue, 28 Aug 2018 18:22:00 +0000 Subject: [PATCH] win,tty: avoid regressions in utf-8 handling This code already had special handling for decoding utf-8 characters correctly for the UCS-2 conhost (trailing incomplete bytes and characters > 0xFFFF). Rather than trying to duplicate that, we can simply delete the duplicate code-path and selectively disable the parts that do not apply. PR-URL: https://github.com/libuv/libuv/pull/1965 Ref: https://github.com/JuliaLang/julia/issues/27267 Co-authored-by: Mustafa M. Reviewed-By: Ben Noordhuis --- src/win/tty.c | 68 +++++++++------------------------------------------ 1 file changed, 11 insertions(+), 57 deletions(-) diff --git a/src/win/tty.c b/src/win/tty.c index 5d5b92d0..517aa4af 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -1625,28 +1625,16 @@ static int uv_tty_write_bufs(uv_tty_t* handle, /* We can only write 8k characters at a time. Windows can't handle much more * characters in a single console write anyway. */ WCHAR utf16_buf[MAX_CONSOLE_CHAR]; - WCHAR* utf16_buffer; DWORD utf16_buf_used = 0; - unsigned int i, len, max_len, pos; - int allocate = 0; + unsigned int i; -#define FLUSH_TEXT() \ - do { \ - pos = 0; \ - do { \ - len = utf16_buf_used - pos; \ - if (len > MAX_CONSOLE_CHAR) \ - len = MAX_CONSOLE_CHAR; \ - uv_tty_emit_text(handle, &utf16_buffer[pos], len, error); \ - pos += len; \ - } while (pos < utf16_buf_used); \ - if (allocate) { \ - uv__free(utf16_buffer); \ - allocate = 0; \ - utf16_buffer = utf16_buf; \ - } \ - utf16_buf_used = 0; \ - } while (0) +#define FLUSH_TEXT() \ + do { \ + if (utf16_buf_used > 0) { \ + uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error); \ + utf16_buf_used = 0; \ + } \ + } while (0) #define ENSURE_BUFFER_SPACE(wchars_needed) \ if (wchars_needed > ARRAY_SIZE(utf16_buf) - utf16_buf_used) { \ @@ -1663,48 +1651,12 @@ static int uv_tty_write_bufs(uv_tty_t* handle, * keep parsing the buffer so we leave the parser in a consistent state. */ *error = ERROR_SUCCESS; - utf16_buffer = utf16_buf; - uv_sem_wait(&uv_tty_output_lock); for (i = 0; i < nbufs; i++) { uv_buf_t buf = bufs[i]; unsigned int j; - if (uv__vterm_state == UV_TTY_SUPPORTED && buf.len > 0) { - utf16_buf_used = MultiByteToWideChar(CP_UTF8, - 0, - buf.base, - buf.len, - NULL, - 0); - - if (utf16_buf_used == 0) { - *error = GetLastError(); - break; - } - - max_len = (utf16_buf_used + 1) * sizeof(WCHAR); - allocate = max_len > MAX_CONSOLE_CHAR; - if (allocate) - utf16_buffer = uv__malloc(max_len); - if (!MultiByteToWideChar(CP_UTF8, - 0, - buf.base, - buf.len, - utf16_buffer, - utf16_buf_used)) { - if (allocate) - uv__free(utf16_buffer); - *error = GetLastError(); - break; - } - - FLUSH_TEXT(); - - continue; - } - for (j = 0; j < buf.len; j++) { unsigned char c = buf.base[j]; @@ -1761,7 +1713,9 @@ static int uv_tty_write_bufs(uv_tty_t* handle, } /* Parse vt100/ansi escape codes */ - if (ansi_parser_state == ANSI_NORMAL) { + if (uv__vterm_state == UV_TTY_SUPPORTED) { + /* Pass through escape codes if conhost supports them. */ + } else if (ansi_parser_state == ANSI_NORMAL) { switch (utf8_codepoint) { case '\033': ansi_parser_state = ANSI_ESCAPE_SEEN;