API: validation: mention invalid method name (#8489)

This commit is contained in:
Justin M. Keyes 2018-06-07 10:56:44 +02:00 committed by GitHub
parent 5a82afa17a
commit 3abf17ae88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 37 additions and 11 deletions

View File

@ -29,6 +29,8 @@ static void msgpack_rpc_add_method_handler(String method,
map_put(String, MsgpackRpcRequestHandler)(methods, method, handler);
}
/// @param name API method name
/// @param name_len name size (includes terminating NUL)
MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
size_t name_len)
{

View File

@ -16,6 +16,7 @@
#include "nvim/api/private/dispatch.h"
#include "nvim/api/buffer.h"
#include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/lua/executor.h"
#include "nvim/vim.h"
#include "nvim/buffer.h"
@ -1163,6 +1164,11 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
MsgpackRpcRequestHandler handler = msgpack_rpc_get_handler_for(name.data,
name.size);
if (handler.fn == msgpack_rpc_handle_missing_method) {
api_set_error(&nested_error, kErrorTypeException, "Invalid method: %s",
name.size > 0 ? name.data : "<empty>");
break;
}
Object result = handler.fn(channel_id, args, &nested_error);
if (ERROR_SET(&nested_error)) {
// error handled after loop

View File

@ -312,24 +312,30 @@ static void handle_request(Channel *channel, msgpack_object *request)
api_clear_error(&error);
return;
}
// Retrieve the request handler
MsgpackRpcRequestHandler handler;
Array args = ARRAY_DICT_INIT;
msgpack_object *method = msgpack_rpc_method(request);
if (method) {
handler = msgpack_rpc_get_handler_for(method->via.bin.ptr,
method->via.bin.size);
if (handler.fn == msgpack_rpc_handle_missing_method) {
String m = method->via.bin.size > 0
? cbuf_to_string(method->via.bin.ptr, method->via.bin.size)
: cstr_to_string("<empty>");
ADD(args, STRING_OBJ(m));
handler.async = true;
} else if (!msgpack_rpc_to_array(msgpack_rpc_args(request), &args)) {
handler.fn = msgpack_rpc_handle_invalid_arguments;
handler.async = true;
}
} else {
handler.fn = msgpack_rpc_handle_missing_method;
handler.async = true;
}
Array args = ARRAY_DICT_INIT;
if (!msgpack_rpc_to_array(msgpack_rpc_args(request), &args)) {
handler.fn = msgpack_rpc_handle_invalid_arguments;
handler.async = true;
}
RequestEvent *evdata = xmalloc(sizeof(RequestEvent));
evdata->channel = channel;
evdata->handler = handler;

View File

@ -493,7 +493,8 @@ Object msgpack_rpc_handle_missing_method(uint64_t channel_id,
Array args,
Error *error)
{
api_set_error(error, kErrorTypeException, "Invalid method name");
api_set_error(error, kErrorTypeException, "Invalid method: %s",
args.size > 0 ? args.items[0].data.string.data : "?");
return NIL;
}

View File

@ -31,7 +31,7 @@ end
local function on_notification(event, args)
if event == 'ping' and #args == 0 then
session:notify("vim_eval", "rpcnotify(g:channel, 'pong')")
session:notify("nvim_eval", "rpcnotify(g:channel, 'pong')")
end
end

View File

@ -222,7 +222,7 @@ describe('server -> client', function()
end)
it('returns an error if the request failed', function()
expect_err('Vim:Invalid method name',
expect_err('Vim:Invalid method: does%-not%-exist',
eval, "rpcrequest(vim, 'does-not-exist')")
end)
end)

View File

@ -20,9 +20,20 @@ local format_string = global_helpers.format_string
local intchar2lua = global_helpers.intchar2lua
local mergedicts_copy = global_helpers.mergedicts_copy
describe('api', function()
describe('API', function()
before_each(clear)
it('validates requests', function()
expect_err('Invalid method: bogus',
request, 'bogus')
expect_err('Invalid method: … の り 。…',
request, '… の り 。…')
expect_err('Invalid method: <empty>',
request, '')
expect_err("can't serialize object",
request, nil)
end)
describe('nvim_command', function()
it('works', function()
local fname = helpers.tmpname()
@ -924,7 +935,7 @@ describe('api', function()
{'i_am_not_a_method', {'xx'}},
{'nvim_set_var', {'avar', 10}},
}
eq({{}, {0, error_types.Exception.id, 'Invalid method name'}},
eq({{}, {0, error_types.Exception.id, 'Invalid method: i_am_not_a_method'}},
meths.call_atomic(req))
eq(5, meths.get_var('avar'))
end)