From 88bc9f8e92903700494486fe383c6b94eef80f3f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 31 Jan 2017 17:42:22 +0100 Subject: xstrlcat: Allow overlapped pointers. (#6017) memcpy is not equivalent to memmove (which is used by vim_strcat), this could cause subtle bugs if xstrlcat is used as a replacement for vim_strcat. But vim_strcat is inconsistent: in the `else` branch it uses strcpy, which doesn't allow overlap. Helped-by: oni-link Helped-by: James McCoy Helped-by: Nikolai Aleksandrovich Pavlov --- test/unit/memory_spec.lua | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test/unit/memory_spec.lua (limited to 'test/unit/memory_spec.lua') diff --git a/test/unit/memory_spec.lua b/test/unit/memory_spec.lua new file mode 100644 index 0000000000..73a32724ef --- /dev/null +++ b/test/unit/memory_spec.lua @@ -0,0 +1,51 @@ +local helpers = require("test.unit.helpers") + +local cimport = helpers.cimport +local cstr = helpers.cstr +local eq = helpers.eq +local ffi = helpers.ffi +local to_cstr = helpers.to_cstr + +local cimp = cimport('stdlib.h', './src/nvim/memory.h') + +describe('xstrlcat()', function() + local function test_xstrlcat(dst, src, dsize) + assert.is_true(dsize >= 1 + string.len(dst)) -- sanity check for tests + local dst_cstr = cstr(dsize, dst) + local src_cstr = to_cstr(src) + eq(string.len(dst .. src), cimp.xstrlcat(dst_cstr, src_cstr, dsize)) + return ffi.string(dst_cstr) + end + + local function test_xstrlcat_overlap(dst, src_idx, dsize) + assert.is_true(dsize >= 1 + string.len(dst)) -- sanity check for tests + local dst_cstr = cstr(dsize, dst) + local src_cstr = dst_cstr + src_idx -- pointer into `dst` (overlaps) + eq(string.len(dst) + string.len(dst) - src_idx, + cimp.xstrlcat(dst_cstr, src_cstr, dsize)) + return ffi.string(dst_cstr) + end + + it('concatenates strings', function() + eq('ab', test_xstrlcat('a', 'b', 3)) + eq('ab', test_xstrlcat('a', 'b', 4096)) + eq('ABCיהZdefgiיהZ', test_xstrlcat('ABCיהZ', 'defgiיהZ', 4096)) + eq('b', test_xstrlcat('', 'b', 4096)) + eq('a', test_xstrlcat('a', '', 4096)) + end) + + it('concatenates overlapping strings', function() + eq('abcabc', test_xstrlcat_overlap('abc', 0, 7)) + eq('abca', test_xstrlcat_overlap('abc', 0, 5)) + eq('abcb', test_xstrlcat_overlap('abc', 1, 5)) + eq('abcc', test_xstrlcat_overlap('abc', 2, 10)) + eq('abcabc', test_xstrlcat_overlap('abc', 0, 2343)) + end) + + it('truncates if `dsize` is too small', function() + eq('a', test_xstrlcat('a', 'b', 2)) + eq('', test_xstrlcat('', 'b', 1)) + eq('ABCיהZd', test_xstrlcat('ABCיהZ', 'defgiיהZ', 10)) + end) + +end) -- cgit