From f6e779d939c0d3c67496daa296b6e78ed10a92b5 Mon Sep 17 00:00:00 2001 From: erw7 Date: Sun, 21 Jul 2019 11:50:11 +0900 Subject: [PATCH 1/2] win/TUI: workaround libuv LF => CRLF conversion #10558 Replace cud1 with \x1b[B because \n is CRLF on Windows (due to libuv). fix #9461 --- src/nvim/tui/tui.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 42e5b9b270..307166bc41 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1585,6 +1585,11 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, unibi_set_if_empty(ut, unibi_set_left_margin_parm, "\x1b[%i%p1%ds"); unibi_set_if_empty(ut, unibi_set_right_margin_parm, "\x1b[%i;%p2%ds"); } + +#ifdef WIN32 + // XXX: workaround libuv implicit LF => CRLF conversion. #10558 + unibi_set_str(ut, unibi_cursor_down, "\x1b[B"); +#endif } else if (rxvt) { // 2017-04 terminfo.src lacks these. Unicode rxvt has them. unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m"); From 465a0a3c09ece20c16c08e694ec9f47aeafb47fc Mon Sep 17 00:00:00 2001 From: erw7 Date: Sun, 21 Jul 2019 16:15:25 +0900 Subject: [PATCH 2/2] env: invalid pointer after os_setenv() #10558 --- src/nvim/os/env.c | 8 +++++++- src/nvim/tui/tui.c | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index b067de608b..2278c325ea 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -105,6 +105,10 @@ bool os_env_exists(const char *name) return (r == 0 || r == UV_ENOBUFS); } +/// Sets an environment variable. +/// +/// @warning Existing pointers to the result of os_getenv("foo") are +/// INVALID after os_setenv("foo", …). int os_setenv(const char *name, const char *value, int overwrite) FUNC_ATTR_NONNULL_ALL { @@ -121,9 +125,11 @@ int os_setenv(const char *name, const char *value, int overwrite) } #endif uv_mutex_lock(&mutex); - pmap_del2(envmap, name); int r = uv_os_setenv(name, value); assert(r != UV_EINVAL); + // Destroy the old map item. Do this AFTER uv_os_setenv(), because `value` + // could be a previous os_getenv() result. + pmap_del2(envmap, name); if (r != 0) { ELOG("uv_os_setenv(%s) failed: %d %s", name, r, uv_err_name(r)); } diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 307166bc41..58ef540707 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -222,6 +222,8 @@ static void terminfo_start(UI *ui) #ifdef WIN32 os_tty_guess_term(&term, data->out_fd); os_setenv("TERM", term, 1); + // Old os_getenv() pointer is invalid after os_setenv(), fetch it again. + term = os_getenv("TERM"); #endif // Set up unibilium/terminfo.