From 063d8a5773b8c0a1a3cac97c7b72c91d560264cf Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Tue, 17 Jun 2014 10:01:26 -0300 Subject: msgpack_rpc: Deal with deserialization failures There seems to be no way to deal with failures when calling `msgpack_unpacker_next`, so this reimplements that function as `msgpack_rpc_unpack`, which has an additional result for detecting failures. On top of that, we make use of the new function to properly return msgpack-rpc errors when something bad happens. --- src/nvim/os/msgpack_rpc.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src/nvim/os/msgpack_rpc.c') diff --git a/src/nvim/os/msgpack_rpc.c b/src/nvim/os/msgpack_rpc.c index 932a7717fd..63e1245028 100644 --- a/src/nvim/os/msgpack_rpc.c +++ b/src/nvim/os/msgpack_rpc.c @@ -79,11 +79,13 @@ void msgpack_rpc_call(uint64_t id, msgpack_object *req, msgpack_packer *res) "Request array size is %u, it should be 4", req->via.array.size); msgpack_rpc_error(error_msg, res); + return; } if (req->via.array.ptr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { msgpack_pack_int(res, 0); // no message id yet msgpack_rpc_error("Id must be a positive integer", res); + return; } // Set the response id, which is the same as the request @@ -398,6 +400,31 @@ void msgpack_rpc_free_dictionary(Dictionary value) free(value.items); } +UnpackResult msgpack_rpc_unpack(msgpack_unpacker* unpacker, + msgpack_unpacked* result) +{ + if (result->zone != NULL) { + msgpack_zone_free(result->zone); + } + + int res = msgpack_unpacker_execute(unpacker); + + if (res > 0) { + result->zone = msgpack_unpacker_release_zone(unpacker); + result->data = msgpack_unpacker_data(unpacker); + msgpack_unpacker_reset(unpacker); + return kUnpackResultOk; + } + + if (res < 0) { + // Since we couldn't parse it, destroy the data consumed so far + msgpack_unpacker_reset(unpacker); + return kUnpackResultFail; + } + + return kUnpackResultNeedMore; +} + REMOTE_FUNCS_IMPL(Buffer, buffer) REMOTE_FUNCS_IMPL(Window, window) REMOTE_FUNCS_IMPL(Tabpage, tabpage) -- cgit