From 8dbf23181add0393556bdb3f4d026e46c7dcbf1e Mon Sep 17 00:00:00 2001 From: Daniel Bershatsky Date: Fri, 12 Apr 2019 02:30:19 +0200 Subject: RPC: conform message-id type to msgpack-RPC spec According to [MessagePack RPC specification](https://github.com/msgpack-rpc/msgpack-rpc), message ID must be 32-bit unsigned integer. But Neovim implementation uses uint64_t instead of uint32_t. This can have wrong results in the case of large ids or a malformed request, for example: Actual response: [1,18446744073709551615,[1,"Message is not an array"],null] Expected response: [1,4294967295,[1,"Message is not an array"],null] The issue does not affect RPC clients written in dynamically-typed languages like Python. Wrong type of sequence id number breaks RPC clients written statically typed languages like C/C++/Golang: all of them expect uint32_t as message id. Examples: https://github.com/msgpack-rpc/msgpack-rpc-cpp/blob/11268ba2be5954ddbb2b7676c7da576985e45cfc/src/msgpack/rpc/protocol.h#L27 https://github.com/ugorji/go/blob/master/codec/msgpack.go#L993 closes #8850 --- src/nvim/msgpack_rpc/helpers.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/nvim/msgpack_rpc/helpers.c') diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c index d7834fc047..3925dc546a 100644 --- a/src/nvim/msgpack_rpc/helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -489,7 +489,7 @@ void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res) } /// Serializes a msgpack-rpc request or notification(id == 0) -void msgpack_rpc_serialize_request(uint64_t request_id, +void msgpack_rpc_serialize_request(uint32_t request_id, const String method, Array args, msgpack_packer *pac) @@ -499,7 +499,7 @@ void msgpack_rpc_serialize_request(uint64_t request_id, msgpack_pack_int(pac, request_id ? 0 : 2); if (request_id) { - msgpack_pack_uint64(pac, request_id); + msgpack_pack_uint32(pac, request_id); } msgpack_rpc_from_string(method, pac); @@ -507,7 +507,7 @@ void msgpack_rpc_serialize_request(uint64_t request_id, } /// Serializes a msgpack-rpc response -void msgpack_rpc_serialize_response(uint64_t response_id, +void msgpack_rpc_serialize_response(uint32_t response_id, Error *err, Object arg, msgpack_packer *pac) @@ -515,7 +515,7 @@ void msgpack_rpc_serialize_response(uint64_t response_id, { msgpack_pack_array(pac, 4); msgpack_pack_int(pac, 1); - msgpack_pack_uint64(pac, response_id); + msgpack_pack_uint32(pac, response_id); if (ERROR_SET(err)) { // error represented by a [type, message] array @@ -561,7 +561,7 @@ static msgpack_object *msgpack_rpc_msg_id(msgpack_object *req) return obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER ? obj : NULL; } -MessageType msgpack_rpc_validate(uint64_t *response_id, msgpack_object *req, +MessageType msgpack_rpc_validate(uint32_t *response_id, msgpack_object *req, Error *err) { *response_id = 0; @@ -600,7 +600,7 @@ MessageType msgpack_rpc_validate(uint64_t *response_id, msgpack_object *req, api_set_error(err, kErrorTypeValidation, "ID must be a positive integer"); return type; } - *response_id = id_obj->via.u64; + *response_id = (uint32_t)id_obj->via.u64; } if (!msgpack_rpc_method(req)) { -- cgit