mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 04:17:01 +00:00 
			
		
		
		
	API: validation: mention invalid method name (#8489)
This commit is contained in:
		| @@ -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) | ||||
| { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Justin M. Keyes
					Justin M. Keyes