From cee9a8ce8a0a6bfdadec7f95466bec73a8cc0bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Linse?= Date: Tue, 27 Feb 2018 10:02:04 +0100 Subject: [PATCH] message: don't output unprintable chars to screen fixes #7586 #8070 --- src/nvim/message.c | 16 +++--- test/functional/ui/input_spec.lua | 90 +++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 10 deletions(-) diff --git a/src/nvim/message.c b/src/nvim/message.c index 1d9a4de9c0..e522670a65 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1825,17 +1825,13 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, } while (msg_col & 7); } else if (*s == BELL) { // beep (from ":sh") vim_beep(BO_SH); - } else { - if (has_mbyte) { - cw = (*mb_ptr2cells)(s); - if (enc_utf8 && maxlen >= 0) - /* avoid including composing chars after the end */ - l = utfc_ptr2len_len(s, (int)((str + maxlen) - s)); - else - l = (*mb_ptr2len)(s); + } else if (*s >= 0x20) { // printable char + cw = mb_ptr2cells(s); + if (maxlen >= 0) { + // avoid including composing chars after the end + l = utfc_ptr2len_len(s, (int)((str + maxlen) - s)); } else { - cw = 1; - l = 1; + l = utfc_ptr2len(s); } // When drawing from right to left or when a double-wide character // doesn't fit, draw a single character here. Otherwise collect diff --git a/test/functional/ui/input_spec.lua b/test/functional/ui/input_spec.lua index f8842901c1..7d5521485c 100644 --- a/test/functional/ui/input_spec.lua +++ b/test/functional/ui/input_spec.lua @@ -2,6 +2,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear, feed_command, nvim = helpers.clear, helpers.feed_command, helpers.nvim local feed, next_message, eq = helpers.feed, helpers.next_message, helpers.eq local expect = helpers.expect +local write_file = helpers.write_file local Screen = require('test.functional.ui.screen') describe('mappings', function() @@ -124,3 +125,92 @@ describe('input utf sequences that contain CSI/K_SPECIAL', function() expect('…') end) end) + +describe('input non-printable chars', function() + it("doesn't crash when echoing them back", function() + write_file("Xtest-overwrite", [[foobar]]) + clear() + local screen = Screen.new(60,8) + screen:set_default_attr_ids({ + [1] = {bold = true, foreground = Screen.colors.Blue1}, + [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, + [3] = {bold = true, foreground = Screen.colors.SeaGreen4} + }) + screen:attach() + + feed_command("e Xtest-overwrite") + screen:expect([[ + ^foobar | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + "Xtest-overwrite" [noeol] 1L, 6C | + ]]) + + -- The timestamp is in second resolution, wait two seconds to be sure. + screen:sleep(2000) + write_file("Xtest-overwrite", [[smurf]]) + feed_command("w") + screen:expect([[ + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + "Xtest-overwrite" | + {2:WARNING: The file has been changed since reading it!!!} | + {3:Do you really want to write to it (y/n)?}^ | + ]]) + + feed("u") + screen:expect([[ + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + "Xtest-overwrite" | + {2:WARNING: The file has been changed since reading it!!!} | + {3:Do you really want to write to it (y/n)?}u | + {3:Do you really want to write to it (y/n)?}^ | + ]]) + + feed("\005") + screen:expect([[ + {1:~ }| + {1:~ }| + {1:~ }| + "Xtest-overwrite" | + {2:WARNING: The file has been changed since reading it!!!} | + {3:Do you really want to write to it (y/n)?}u | + {3:Do you really want to write to it (y/n)?} | + {3:Do you really want to write to it (y/n)?}^ | + ]]) + + feed("n") + screen:expect([[ + {1:~ }| + {1:~ }| + "Xtest-overwrite" | + {2:WARNING: The file has been changed since reading it!!!} | + {3:Do you really want to write to it (y/n)?}u | + {3:Do you really want to write to it (y/n)?} | + {3:Do you really want to write to it (y/n)?}n | + {3:Press ENTER or type command to continue}^ | + ]]) + + feed("") + screen:expect([[ + ^foobar | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + end) +end)