From 7217360e349ff787933d91b55efdfeb435eb45cb Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 6 Mar 2017 10:44:07 -0500 Subject: [PATCH 1/4] vim-patch:7.4.2051 Problem: No proper testing of trunc_string(). Solution: Add a unittest for message.c. https://github.com/vim/vim/commit/502ae4ba63561c98ac69af26cd9883bfd18d225f --- src/nvim/message.c | 2 +- src/nvim/version.c | 2 +- test/functional/ui/inccommand_spec.lua | 18 +++++----- test/unit/message_spec.lua | 49 ++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 test/unit/message_spec.lua diff --git a/src/nvim/message.c b/src/nvim/message.c index 699f4b87b9..57f7369e73 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -257,7 +257,7 @@ void trunc_string(char_u *s, char_u *buf, int room, int buflen) return; } n = ptr2cells(s + e); - if (len + n >= half) + if (len + n > half) break; len += n; buf[e] = s[e]; diff --git a/src/nvim/version.c b/src/nvim/version.c index 8fd9b4b74f..b755404a58 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -389,7 +389,7 @@ static int included_patches[] = { // 2054 NA // 2053 NA // 2052 NA - // 2051, + 2051, 2050, 2049, // 2048 NA diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 6da22b6a3a..3b31da0397 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -482,7 +482,7 @@ describe(":substitute, 'inccommand' preserves undo", function() {15:~ }| {15:~ }| {15:~ }| - Already...st change | + Already ...t change | ]]) else screen:expect([[ @@ -495,7 +495,7 @@ describe(":substitute, 'inccommand' preserves undo", function() {15:~ }| {15:~ }| {15:~ }| - Already...st change | + Already ...t change | ]]) end end @@ -534,7 +534,7 @@ describe(":substitute, 'inccommand' preserves undo", function() {15:~ }| {15:~ }| {15:~ }| - Already...st change | + Already ...t change | ]]) else screen:expect([[ @@ -547,7 +547,7 @@ describe(":substitute, 'inccommand' preserves undo", function() {15:~ }| {15:~ }| {15:~ }| - Already...st change | + Already ...t change | ]]) end @@ -574,7 +574,7 @@ describe(":substitute, 'inccommand' preserves undo", function() {15:~ }| {15:~ }| {15:~ }| - Already...st change | + Already ...t change | ]]) else screen:expect([[ @@ -587,7 +587,7 @@ describe(":substitute, 'inccommand' preserves undo", function() {15:~ }| {15:~ }| {15:~ }| - Already...st change | + Already ...t change | ]]) end screen:detach() @@ -616,7 +616,7 @@ describe(":substitute, 'inccommand' preserves undo", function() {15:~ }| {15:~ }| {15:~ }| - Already...st change | + Already ...t change | ]]) else screen:expect([[ @@ -629,7 +629,7 @@ describe(":substitute, 'inccommand' preserves undo", function() {15:~ }| {15:~ }| {15:~ }| - Already...st change | + Already ...t change | ]]) end @@ -653,7 +653,7 @@ describe(":substitute, 'inccommand' preserves undo", function() {15:~ }| {15:~ }| {15:~ }| - Already...st change | + Already ...t change | ]]) end screen:detach() diff --git a/test/unit/message_spec.lua b/test/unit/message_spec.lua new file mode 100644 index 0000000000..23d342c027 --- /dev/null +++ b/test/unit/message_spec.lua @@ -0,0 +1,49 @@ +local helpers = require("test.unit.helpers") + +local ffi = helpers.ffi +local eq = helpers.eq +local to_cstr = helpers.to_cstr + +local cimp = helpers.cimport('./src/nvim/message.h') + +describe('trunc_string', function() + local buffer = ffi.typeof('char_u[40]') + + local function test_inplace(s, expected) + local buf = buffer() + ffi.C.strcpy(buf, s) + cimp.trunc_string(buf, buf, 20, 40) + eq(expected, ffi.string(buf)) + end + + local function test_copy(s, expected) + local buf = buffer() + cimp.trunc_string(to_cstr(s), buf, 20, 40) + eq(expected, ffi.string(buf)) + end + + local permutations = { + { ['desc'] = 'in-place', ['func'] = test_inplace }, + { ['desc'] = 'by copy', ['func'] = test_copy }, + } + + for _,t in ipairs(permutations) do + describe('populates buf '..t.desc, function() + it('with a small string', function() + t.func('text', 'text') + end) + + it('with a medium string', function() + t.func('a short text', 'a short text') + end) + + it('with a string exactly the truncate size', function() + t.func('a text tha just fits', 'a text tha just fits') + end) + + it('with a string that must be truncated', function() + t.func('a text that nott fits', 'a text t...nott fits') + end) + end) + end +end) From 4e3a2784ec3cb4ff79bd48f55a8edee817dec6e7 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 6 Mar 2017 12:14:39 -0500 Subject: [PATCH 2/4] vim-patch:7.4.2068 Problem: Not all arguments of trunc_string() are tested. Memory access error when running the message tests. Solution: Add another test case. (Yegappan Lakshmanan) Make it easy to run unittests with valgrind. Fix the access error. https://github.com/vim/vim/commit/b9644433d2728e99fab874e5e33147ad95d23a31 --- src/nvim/message.c | 4 ++-- src/nvim/version.c | 2 +- test/unit/message_spec.lua | 28 +++++++++++++++++++--------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/nvim/message.c b/src/nvim/message.c index 57f7369e73..689e8893bd 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -274,9 +274,9 @@ void trunc_string(char_u *s, char_u *buf, int room, int buflen) for (;;) { do { half = half - (*mb_head_off)(s, s + half - 1) - 1; - } while (utf_iscomposing(utf_ptr2char(s + half)) && half > 0); + } while (half > 0 && utf_iscomposing(utf_ptr2char(s + half))); n = ptr2cells(s + half); - if (len + n > room) { + if (len + n > room || half == 0) { break; } len += n; diff --git a/src/nvim/version.c b/src/nvim/version.c index b755404a58..abd3b7dfc3 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -372,7 +372,7 @@ static int included_patches[] = { 2071, // 2070 NA // 2069, - // 2068, + 2068, 2067, 2066, 2065, diff --git a/test/unit/message_spec.lua b/test/unit/message_spec.lua index 23d342c027..afb572347f 100644 --- a/test/unit/message_spec.lua +++ b/test/unit/message_spec.lua @@ -4,22 +4,28 @@ local ffi = helpers.ffi local eq = helpers.eq local to_cstr = helpers.to_cstr -local cimp = helpers.cimport('./src/nvim/message.h') +local cimp = helpers.cimport('./src/nvim/message.h', './src/nvim/memory.h', + './src/nvim/strings.h') describe('trunc_string', function() - local buffer = ffi.typeof('char_u[40]') - - local function test_inplace(s, expected) - local buf = buffer() + local buflen = 40 + local function test_inplace(s, expected, room) + room = room and room or 20 + local buf = cimp.xmalloc(ffi.sizeof('char_u') * buflen) ffi.C.strcpy(buf, s) - cimp.trunc_string(buf, buf, 20, 40) + cimp.trunc_string(buf, buf, room, buflen) eq(expected, ffi.string(buf)) + cimp.xfree(buf) end - local function test_copy(s, expected) - local buf = buffer() - cimp.trunc_string(to_cstr(s), buf, 20, 40) + local function test_copy(s, expected, room) + room = room and room or 20 + local buf = cimp.xmalloc(ffi.sizeof('char_u') * buflen) + local str = cimp.vim_strsave(to_cstr(s)) + cimp.trunc_string(str, buf, room, buflen) eq(expected, ffi.string(buf)) + cimp.xfree(buf) + cimp.xfree(str) end local permutations = { @@ -37,6 +43,10 @@ describe('trunc_string', function() t.func('a short text', 'a short text') end) + it('with a string of length == 1/2 room', function() + t.func('a text that fits', 'a text that fits', 34) + end) + it('with a string exactly the truncate size', function() t.func('a text tha just fits', 'a text tha just fits') end) From 52e56954c6fa211246a55f7877986473d21a238b Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 6 Mar 2017 13:31:39 -0500 Subject: [PATCH 3/4] vim-patch:7.4.2097 Problem: Warning from 64 bit compiler. Solution: use size_t instead of int. (Mike Williams) https://github.com/vim/vim/commit/d4f31dc45482e8db527ca044b9c3436b1e750006 --- src/nvim/message.c | 18 ++++++++++-------- src/nvim/version.c | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/nvim/message.c b/src/nvim/message.c index 689e8893bd..9d9bed2c1f 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -237,17 +237,19 @@ msg_strtrunc ( * Truncate a string "s" to "buf" with cell width "room". * "s" and "buf" may be equal. */ -void trunc_string(char_u *s, char_u *buf, int room, int buflen) +void trunc_string(char_u *s, char_u *buf, int room_in, int buflen) { - int half; - int len; + size_t room = room_in - 3; // "..." takes 3 chars + size_t half; + size_t len = 0; int e; int i; int n; - room -= 3; + if (room_in < 3) { + room = 0; + } half = room / 2; - len = 0; /* First part: Start of the string. */ for (e = 0; len < half && e < buflen; ++e) { @@ -287,7 +289,7 @@ void trunc_string(char_u *s, char_u *buf, int room, int buflen) // text fits without truncating if (s != buf) { len = STRLEN(s); - if (len >= buflen) { + if (len >= (size_t)buflen) { len = buflen - 1; } len = len - e + 1; @@ -300,8 +302,8 @@ void trunc_string(char_u *s, char_u *buf, int room, int buflen) } else if (e + 3 < buflen) { // set the middle and copy the last part memmove(buf + e, "...", (size_t)3); - len = (int)STRLEN(s + i) + 1; - if (len >= buflen - e - 3) + len = STRLEN(s + i) + 1; + if (len >= (size_t)buflen - e - 3) len = buflen - e - 3 - 1; memmove(buf + e + 3, s + i, len); buf[e + 3 + len - 1] = NUL; diff --git a/src/nvim/version.c b/src/nvim/version.c index abd3b7dfc3..1771e2b95e 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -343,7 +343,7 @@ static int included_patches[] = { 2100, 2099, 2098, - // 2097, + 2097, 2096, 2095, // 2094 NA From 532197b4f95596e202fb230523ceb0c9e6233dae Mon Sep 17 00:00:00 2001 From: James McCoy Date: Mon, 6 Mar 2017 14:29:26 -0500 Subject: [PATCH 4/4] lint --- src/nvim/message.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/nvim/message.c b/src/nvim/message.c index 9d9bed2c1f..4cd0db21e8 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -259,8 +259,9 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen) return; } n = ptr2cells(s + e); - if (len + n > half) + if (len + n > half) { break; + } len += n; buf[e] = s[e]; if (has_mbyte) @@ -303,8 +304,9 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen) // set the middle and copy the last part memmove(buf + e, "...", (size_t)3); len = STRLEN(s + i) + 1; - if (len >= (size_t)buflen - e - 3) + if (len >= (size_t)buflen - e - 3) { len = buflen - e - 3 - 1; + } memmove(buf + e + 3, s + i, len); buf[e + 3 + len - 1] = NUL; } else {