From d0c26414b4287628b2fef25aa7e3971240a92383 Mon Sep 17 00:00:00 2001 From: Hitesh Kanwathirtha Date: Sun, 13 Nov 2016 02:10:57 -0800 Subject: [PATCH] win, tty: handle empty buffer in uv_tty_write_bufs In uv_tty_write_bufs, if the console supports Virtual Terminal sequences, we try to convert the passed in utf8 buffer to utf16. However, we need to check if the buffer is of non-zero length- otherwise, MultiByteToWideChar returns an error. Fixes: https://github.com/libuv/libuv/issues/1135 Fixes: https://github.com/nodejs/node/issues/9542 PR-URL: https://github.com/libuv/libuv/pull/1139 Refs: https://github.com/libuv/libuv/pull/889 Reviewed-By: Bartosz Sosnowski Reviewed-By: Ben Noordhuis Reviewed-By: Imran Iqbal --- src/win/tty.c | 2 +- test/test-list.h | 2 ++ test/test-tty.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/win/tty.c b/src/win/tty.c index 18d68d09..1e397b44 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -1650,7 +1650,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle, uv_buf_t buf = bufs[i]; unsigned int j; - if (uv__vterm_state == UV_SUPPORTED) { + if (uv__vterm_state == UV_SUPPORTED && buf.len > 0) { utf16_buf_used = MultiByteToWideChar(CP_UTF8, 0, buf.base, diff --git a/test/test-list.h b/test/test-list.h index 08886a6f..6ddd5ff2 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -47,6 +47,7 @@ TEST_DECLARE (semaphore_3) TEST_DECLARE (tty) #ifdef _WIN32 TEST_DECLARE (tty_raw) +TEST_DECLARE (tty_empty_write) #endif TEST_DECLARE (tty_file) TEST_DECLARE (tty_pty) @@ -404,6 +405,7 @@ TASK_LIST_START TEST_ENTRY (tty) #ifdef _WIN32 TEST_ENTRY (tty_raw) + TEST_ENTRY (tty_empty_write) #endif TEST_ENTRY (tty_file) TEST_ENTRY (tty_pty) diff --git a/test/test-tty.c b/test/test-tty.c index d03f07a4..68a03cd1 100644 --- a/test/test-tty.c +++ b/test/test-tty.c @@ -212,6 +212,48 @@ TEST_IMPL(tty_raw) { MAKE_VALGRIND_HAPPY(); return 0; } + +TEST_IMPL(tty_empty_write) { + int r; + int ttyout_fd; + uv_tty_t tty_out; + uv_loop_t* loop = uv_default_loop(); + + /* Make sure we have an FD that refers to a tty */ + HANDLE handle; + + handle = CreateFileA("conout$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyout_fd = _open_osfhandle((intptr_t) handle, 0); + + ASSERT(ttyout_fd >= 0); + + ASSERT(UV_TTY == uv_guess_handle(ttyout_fd)); + + r = uv_tty_init(uv_default_loop(), &tty_out, ttyout_fd, 0); /* Writable. */ + ASSERT(r == 0); + + char dummy[1]; + uv_buf_t bufs[1]; + bufs[0].len = 0; + bufs[0].base = &dummy; + + r = uv_try_write((uv_stream_t*) &tty_out, bufs, 1); + ASSERT(r == 0); + + uv_close((uv_handle_t*) &tty_out, NULL); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} #endif