fix(msgpack): use fixstr encoding for strings of length 20-31 #36737

Problem:
MessagePack fixstr format supports string lengths 0-31, but mpack_str()
only used fixstr for lengths < 20. Strings of 20-31 bytes were
incorrectly encoded as str8 (2-byte header) instead of fixstr (1-byte
header).

Solution:
Change the condition from `len < 20` to `len < 32` to match the
MessagePack specification.

This fix affects message timing which exposed a pre-existing race
condition in the channels_spec PTY test. The test now uses a helper
function to accumulate partial PTY reads, making it more robust.

Fixes #32784
This commit is contained in:
benarcher2691
2025-12-01 19:16:44 +01:00
committed by GitHub
parent 1de77c608f
commit 7f2d5d6883
3 changed files with 32 additions and 2 deletions

View File

@@ -27,4 +27,18 @@ describe('lua vim.mpack', function()
end)
)
end)
it('encodes dict keys of length 20-31 as fixstr #32784', function()
-- MessagePack fixstr format: 0xa0 | length (for lengths 0-31)
-- Before #36737, strings 20-31 bytes were incorrectly encoded as str8 (0xd9, len)
for len = 20, 31 do
local expected_header = string.char(0xa0 + len) -- fixstr header
local result = exec_lua(function(keylen)
local key = string.rep('x', keylen)
return vim.mpack.encode({ [key] = 1 })
end, len)
-- Byte 1 is fixmap header (0x81), byte 2 should be fixstr header for the key
eq(expected_header, result:sub(2, 2), 'dict key length ' .. len .. ' should use fixstr')
end
end)
end)