diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/os/channel.c | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/src/nvim/os/channel.c b/src/nvim/os/channel.c index 7cc40a67e0..a0575de2e9 100644 --- a/src/nvim/os/channel.c +++ b/src/nvim/os/channel.c @@ -207,12 +207,12 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof) msgpack_unpacked unpacked; msgpack_unpacked_init(&unpacked); UnpackResult result; - msgpack_packer response; // Deserialize everything we can. while ((result = msgpack_rpc_unpack(channel->unpacker, &unpacked)) == kUnpackResultOk) { // Each object is a new msgpack-rpc request and requires an empty response + msgpack_packer response; msgpack_packer_init(&response, channel->sbuffer, msgpack_sbuffer_write); // Perform the call msgpack_rpc_call(channel->id, &unpacked.data, &response); @@ -234,24 +234,35 @@ static void parse_msgpack(RStream *rstream, void *data, bool eof) // A not so uncommon cause for this might be deserializing objects with // a high nesting level: msgpack will break when it's internal parse stack // size exceeds MSGPACK_EMBED_STACK_SIZE(defined as 32 by default) - msgpack_packer_init(&response, channel->sbuffer, msgpack_sbuffer_write); - msgpack_pack_array(&response, 4); - msgpack_pack_int(&response, 1); - msgpack_pack_int(&response, 0); - msgpack_rpc_error("Invalid msgpack payload. " - "This error can also happen when deserializing " - "an object with high level of nesting", - &response); - WBuffer *buffer = wstream_new_buffer(xmemdup(channel->sbuffer->data, - channel->sbuffer->size), - channel->sbuffer->size, - free); - if (!channel_write(channel, buffer)) { - return; - } - // Clear the buffer for future calls - msgpack_sbuffer_clear(channel->sbuffer); + send_error(channel, "Invalid msgpack payload. " + "This error can also happen when deserializing " + "an object with high level of nesting"); + } +} + +static void send_error(Channel *channel, char *msg) +{ + msgpack_packer err; + // See src/msgpack/unpack_template.h in msgpack source tree for + // causes for this error(search for 'goto _failed') + // + // A not so uncommon cause for this might be deserializing objects with + // a high nesting level: msgpack will break when it's internal parse stack + // size exceeds MSGPACK_EMBED_STACK_SIZE(defined as 32 by default) + msgpack_packer_init(&err, channel->sbuffer, msgpack_sbuffer_write); + msgpack_pack_array(&err, 4); + msgpack_pack_int(&err, 1); + msgpack_pack_int(&err, 0); + msgpack_rpc_error(msg, &err); + WBuffer *buffer = wstream_new_buffer(xmemdup(channel->sbuffer->data, + channel->sbuffer->size), + channel->sbuffer->size, + free); + if (!channel_write(channel, buffer)) { + return; } + // Clear the buffer for future calls + msgpack_sbuffer_clear(channel->sbuffer); } static bool channel_write(Channel *channel, WBuffer *buffer) |