aboutsummaryrefslogtreecommitdiff
path: root/test/unit/msgpack_spec.lua
blob: bd663a3c75a621bd7299330339de5072e9c62b97 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
local helpers = require('test.unit.helpers')(after_each)
local cimport = helpers.cimport
local itp = helpers.gen_itp(it)
local lib = cimport('./src/nvim/msgpack_rpc/unpacker.h', './src/nvim/memory.h')
local ffi = helpers.ffi
local eq = helpers.eq
local to_cstr = helpers.to_cstr

--- @class Unpacker
--- @field read_ptr ffi.cdata*
--- @field read_size number

--- @alias Unpacker* table<number, Unpacker>
--- @return Unpacker* unpacker `unpacker[0]` to dereference
local function make_unpacker()
  return ffi.gc(ffi.cast('Unpacker*', lib.xcalloc(1, ffi.sizeof('Unpacker'))), function(unpacker)
    lib.unpacker_teardown(unpacker, nil, nil)
    lib.xfree(unpacker)
  end)
end

--- @param unpacker Unpacker*
--- @param data string
--- @param size number? *default: data:len()*
local function unpacker_goto(unpacker, data, size)
  unpacker[0].read_ptr = to_cstr(data)
  unpacker[0].read_size = size or data:len()
end

--- @param unpacker Unpacker*
--- @return boolean
local function unpacker_advance(unpacker)
  return lib.unpacker_advance(unpacker)
end

describe('msgpack', function()
  describe('unpacker', function()
    itp(
      'does not crash when paused between `cells` and `wrap` params of `grid_line` #25184',
      function()
        -- [kMessageTypeNotification, "redraw", [
        --   ["grid_line",
        --     [2, 0, 0, [[" " , 0, 77]], false]
        --   ]
        -- ]]
        local payload =
          '\x93\x02\xa6\x72\x65\x64\x72\x61\x77\x91\x92\xa9\x67\x72\x69\x64\x5f\x6c\x69\x6e\x65\x95\x02\x00\x00\x91\x93\xa1\x20\x00\x4d\xc2'

        local unpacker = make_unpacker()
        lib.unpacker_init(unpacker)

        unpacker_goto(unpacker, payload, payload:len() - 1)
        local finished = unpacker_advance(unpacker)
        eq(finished, false)

        unpacker[0].read_size = unpacker[0].read_size + 1
        finished = unpacker_advance(unpacker)
        eq(finished, true)
      end
    )

    itp('does not crash when parsing grid_line event with 0 `cells` #25184', function()
      local unpacker = make_unpacker()
      lib.unpacker_init(unpacker)

      unpacker_goto(
        unpacker,
        -- [kMessageTypeNotification, "redraw", [
        --   ["grid_line",
        --     [2, 0, 0, [], false]
        --   ]
        -- ]]
        '\x93\x02\xa6\x72\x65\x64\x72\x61\x77\x91\x92\xa9\x67\x72\x69\x64\x5f\x6c\x69\x6e\x65\x95\x02\x00\x00\x90\xc2'
      )
      local finished = unpacker_advance(unpacker)
      eq(finished, true)
    end)
  end)
end)