mirror of
https://github.com/neovim/neovim.git
synced 2024-12-25 13:45:15 -07:00
Merge #8931 from justinmk/api-error-overrun
This commit is contained in:
commit
8b76034f3b
@ -40,7 +40,8 @@ MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
|
||||
map_get(String, MsgpackRpcRequestHandler)(methods, m);
|
||||
|
||||
if (!rv.fn) {
|
||||
api_set_error(error, kErrorTypeException, "Invalid method: %s",
|
||||
api_set_error(error, kErrorTypeException, "Invalid method: %.*s",
|
||||
m.size > 0 ? m.size : sizeof("<empty>"),
|
||||
m.size > 0 ? m.data : "<empty>");
|
||||
}
|
||||
return rv;
|
||||
|
@ -162,7 +162,7 @@ Object dict_get_value(dict_T *dict, String key, Error *err)
|
||||
dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size);
|
||||
|
||||
if (di == NULL) {
|
||||
api_set_error(err, kErrorTypeValidation, "Key '%s' not found", key.data);
|
||||
api_set_error(err, kErrorTypeValidation, "Key not found: %s", key.data);
|
||||
return (Object)OBJECT_INIT;
|
||||
}
|
||||
|
||||
@ -191,13 +191,12 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del,
|
||||
}
|
||||
|
||||
if (key.size == 0) {
|
||||
api_set_error(err, kErrorTypeValidation,
|
||||
"Empty variable names aren't allowed");
|
||||
api_set_error(err, kErrorTypeValidation, "Key name is empty");
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (key.size > INT_MAX) {
|
||||
api_set_error(err, kErrorTypeValidation, "Key length is too high");
|
||||
api_set_error(err, kErrorTypeValidation, "Key name is too long");
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -220,7 +219,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del,
|
||||
// Delete the key
|
||||
if (di == NULL) {
|
||||
// Doesn't exist, fail
|
||||
api_set_error(err, kErrorTypeValidation, "Key does not exist: %s",
|
||||
api_set_error(err, kErrorTypeValidation, "Key not found: %s",
|
||||
key.data);
|
||||
} else {
|
||||
// Return the old value
|
||||
@ -284,9 +283,7 @@ Object get_option_from(void *from, int type, String name, Error *err)
|
||||
type, from);
|
||||
|
||||
if (!flags) {
|
||||
api_set_error(err,
|
||||
kErrorTypeValidation,
|
||||
"Invalid option name \"%s\"",
|
||||
api_set_error(err, kErrorTypeValidation, "Invalid option name: '%s'",
|
||||
name.data);
|
||||
return rv;
|
||||
}
|
||||
@ -303,15 +300,14 @@ Object get_option_from(void *from, int type, String name, Error *err)
|
||||
rv.data.string.data = stringval;
|
||||
rv.data.string.size = strlen(stringval);
|
||||
} else {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Unable to get value for option \"%s\"",
|
||||
api_set_error(err, kErrorTypeException,
|
||||
"Failed to get value for option '%s'",
|
||||
name.data);
|
||||
}
|
||||
} else {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Unknown type for option \"%s\"",
|
||||
"Unknown type for option '%s'",
|
||||
name.data);
|
||||
}
|
||||
|
||||
@ -336,24 +332,20 @@ void set_option_to(uint64_t channel_id, void *to, int type,
|
||||
int flags = get_option_value_strict(name.data, NULL, NULL, type, to);
|
||||
|
||||
if (flags == 0) {
|
||||
api_set_error(err,
|
||||
kErrorTypeValidation,
|
||||
"Invalid option name \"%s\"",
|
||||
api_set_error(err, kErrorTypeValidation, "Invalid option name '%s'",
|
||||
name.data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.type == kObjectTypeNil) {
|
||||
if (type == SREQ_GLOBAL) {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Unable to unset option \"%s\"",
|
||||
api_set_error(err, kErrorTypeException, "Cannot unset option '%s'",
|
||||
name.data);
|
||||
return;
|
||||
} else if (!(flags & SOPT_GLOBAL)) {
|
||||
api_set_error(err,
|
||||
kErrorTypeException,
|
||||
"Cannot unset option \"%s\" "
|
||||
"Cannot unset option '%s' "
|
||||
"because it doesn't have a global value",
|
||||
name.data);
|
||||
return;
|
||||
@ -370,7 +362,7 @@ void set_option_to(uint64_t channel_id, void *to, int type,
|
||||
if (value.type != kObjectTypeBoolean) {
|
||||
api_set_error(err,
|
||||
kErrorTypeValidation,
|
||||
"Option \"%s\" requires a boolean value",
|
||||
"Option '%s' requires a Boolean value",
|
||||
name.data);
|
||||
return;
|
||||
}
|
||||
@ -378,17 +370,15 @@ void set_option_to(uint64_t channel_id, void *to, int type,
|
||||
numval = value.data.boolean;
|
||||
} else if (flags & SOPT_NUM) {
|
||||
if (value.type != kObjectTypeInteger) {
|
||||
api_set_error(err,
|
||||
kErrorTypeValidation,
|
||||
"Option \"%s\" requires an integer value",
|
||||
api_set_error(err, kErrorTypeValidation,
|
||||
"Option '%s' requires an integer value",
|
||||
name.data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.data.integer > INT_MAX || value.data.integer < INT_MIN) {
|
||||
api_set_error(err,
|
||||
kErrorTypeValidation,
|
||||
"Value for option \"%s\" is outside range",
|
||||
api_set_error(err, kErrorTypeValidation,
|
||||
"Value for option '%s' is out of range",
|
||||
name.data);
|
||||
return;
|
||||
}
|
||||
@ -396,9 +386,8 @@ void set_option_to(uint64_t channel_id, void *to, int type,
|
||||
numval = (int)value.data.integer;
|
||||
} else {
|
||||
if (value.type != kObjectTypeString) {
|
||||
api_set_error(err,
|
||||
kErrorTypeValidation,
|
||||
"Option \"%s\" requires a string value",
|
||||
api_set_error(err, kErrorTypeValidation,
|
||||
"Option '%s' requires a string value",
|
||||
name.data);
|
||||
return;
|
||||
}
|
||||
|
@ -502,7 +502,7 @@ Integer nvim_strwidth(String text, Error *err)
|
||||
FUNC_API_SINCE(1)
|
||||
{
|
||||
if (text.size > INT_MAX) {
|
||||
api_set_error(err, kErrorTypeValidation, "String length is too high");
|
||||
api_set_error(err, kErrorTypeValidation, "String is too long");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -559,7 +559,7 @@ void nvim_set_current_dir(String dir, Error *err)
|
||||
FUNC_API_SINCE(1)
|
||||
{
|
||||
if (dir.size >= MAXPATHL) {
|
||||
api_set_error(err, kErrorTypeValidation, "Directory string is too long");
|
||||
api_set_error(err, kErrorTypeValidation, "Directory name is too long");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1136,14 +1136,14 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
|
||||
if (calls.items[i].type != kObjectTypeArray) {
|
||||
api_set_error(err,
|
||||
kErrorTypeValidation,
|
||||
"All items in calls array must be arrays");
|
||||
"Items in calls array must be arrays");
|
||||
goto validation_error;
|
||||
}
|
||||
Array call = calls.items[i].data.array;
|
||||
if (call.size != 2) {
|
||||
api_set_error(err,
|
||||
kErrorTypeValidation,
|
||||
"All items in calls array must be arrays of size 2");
|
||||
"Items in calls array must be arrays of size 2");
|
||||
goto validation_error;
|
||||
}
|
||||
|
||||
|
@ -309,7 +309,7 @@ describe('api/buf', function()
|
||||
eq(1, funcs.exists('b:lua'))
|
||||
curbufmeths.del_var('lua')
|
||||
eq(0, funcs.exists('b:lua'))
|
||||
eq({false, 'Key does not exist: lua'}, meth_pcall(curbufmeths.del_var, 'lua'))
|
||||
eq({false, 'Key not found: lua'}, meth_pcall(curbufmeths.del_var, 'lua'))
|
||||
curbufmeths.set_var('lua', 1)
|
||||
command('lockvar b:lua')
|
||||
eq({false, 'Key is locked: lua'}, meth_pcall(curbufmeths.del_var, 'lua'))
|
||||
|
@ -34,7 +34,7 @@ describe('api/tabpage', function()
|
||||
eq(1, funcs.exists('t:lua'))
|
||||
curtabmeths.del_var('lua')
|
||||
eq(0, funcs.exists('t:lua'))
|
||||
eq({false, 'Key does not exist: lua'}, meth_pcall(curtabmeths.del_var, 'lua'))
|
||||
eq({false, 'Key not found: lua'}, meth_pcall(curtabmeths.del_var, 'lua'))
|
||||
curtabmeths.set_var('lua', 1)
|
||||
command('lockvar t:lua')
|
||||
eq({false, 'Key is locked: lua'}, meth_pcall(curtabmeths.del_var, 'lua'))
|
||||
|
@ -24,13 +24,25 @@ describe('API', function()
|
||||
before_each(clear)
|
||||
|
||||
it('validates requests', function()
|
||||
expect_err('Invalid method: bogus',
|
||||
-- RPC
|
||||
expect_err('Invalid method: bogus$',
|
||||
request, 'bogus')
|
||||
expect_err('Invalid method: … の り 。…',
|
||||
expect_err('Invalid method: … の り 。…$',
|
||||
request, '… の り 。…')
|
||||
expect_err('Invalid method: <empty>',
|
||||
expect_err('Invalid method: <empty>$',
|
||||
request, '')
|
||||
expect_err("can't serialize object",
|
||||
|
||||
-- Non-RPC: rpcrequest(v:servername) uses internal channel.
|
||||
expect_err('Invalid method: … の り 。…$',
|
||||
request, 'nvim_eval',
|
||||
[=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), '… の り 。…')]=])
|
||||
expect_err('Invalid method: bogus$',
|
||||
request, 'nvim_eval',
|
||||
[=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), 'bogus')]=])
|
||||
|
||||
-- XXX: This must be the last one, else next one will fail:
|
||||
-- "Packer instance already working. Use another Packer ..."
|
||||
expect_err("can't serialize object$",
|
||||
request, nil)
|
||||
end)
|
||||
|
||||
@ -158,7 +170,7 @@ describe('API', function()
|
||||
end)
|
||||
|
||||
it("VimL error: returns error details, does NOT update v:errmsg", function()
|
||||
expect_err('E121: Undefined variable: bogus', request,
|
||||
expect_err('E121: Undefined variable: bogus$', request,
|
||||
'nvim_eval', 'bogus expression')
|
||||
eq('', eval('v:errmsg')) -- v:errmsg was not updated.
|
||||
end)
|
||||
@ -173,7 +185,7 @@ describe('API', function()
|
||||
end)
|
||||
|
||||
it("VimL validation error: returns specific error, does NOT update v:errmsg", function()
|
||||
expect_err('E117: Unknown function: bogus function', request,
|
||||
expect_err('E117: Unknown function: bogus function$', request,
|
||||
'nvim_call_function', 'bogus function', {'arg1'})
|
||||
expect_err('E119: Not enough arguments for function: atan', request,
|
||||
'nvim_call_function', 'atan', {})
|
||||
@ -182,11 +194,11 @@ describe('API', function()
|
||||
end)
|
||||
|
||||
it("VimL error: returns error details, does NOT update v:errmsg", function()
|
||||
expect_err('E808: Number or Float required', request,
|
||||
expect_err('E808: Number or Float required$', request,
|
||||
'nvim_call_function', 'atan', {'foo'})
|
||||
expect_err('Invalid channel stream "xxx"', request,
|
||||
expect_err('Invalid channel stream "xxx"$', request,
|
||||
'nvim_call_function', 'chanclose', {999, 'xxx'})
|
||||
expect_err('E900: Invalid channel id', request,
|
||||
expect_err('E900: Invalid channel id$', request,
|
||||
'nvim_call_function', 'chansend', {999, 'foo'})
|
||||
eq('', eval('v:exception'))
|
||||
eq('', eval('v:errmsg')) -- v:errmsg was not updated.
|
||||
@ -198,7 +210,7 @@ describe('API', function()
|
||||
throw 'wtf'
|
||||
endfunction
|
||||
]])
|
||||
expect_err('wtf', request,
|
||||
expect_err('wtf$', request,
|
||||
'nvim_call_function', 'Foo', {})
|
||||
eq('', eval('v:exception'))
|
||||
eq('', eval('v:errmsg')) -- v:errmsg was not updated.
|
||||
@ -212,7 +224,7 @@ describe('API', function()
|
||||
endfunction
|
||||
]])
|
||||
-- E740
|
||||
expect_err('Function called with too many arguments', request,
|
||||
expect_err('Function called with too many arguments$', request,
|
||||
'nvim_call_function', 'Foo', too_many_args)
|
||||
end)
|
||||
end)
|
||||
@ -248,23 +260,23 @@ describe('API', function()
|
||||
|
||||
it('validates args', function()
|
||||
command('let g:d={"baz":"zub","meep":[]}')
|
||||
expect_err('Not found: bogus', request,
|
||||
expect_err('Not found: bogus$', request,
|
||||
'nvim_call_dict_function', 'g:d', 'bogus', {1,2})
|
||||
expect_err('Not a function: baz', request,
|
||||
expect_err('Not a function: baz$', request,
|
||||
'nvim_call_dict_function', 'g:d', 'baz', {1,2})
|
||||
expect_err('Not a function: meep', request,
|
||||
expect_err('Not a function: meep$', request,
|
||||
'nvim_call_dict_function', 'g:d', 'meep', {1,2})
|
||||
expect_err('E117: Unknown function: f', request,
|
||||
expect_err('E117: Unknown function: f$', request,
|
||||
'nvim_call_dict_function', { f = '' }, 'f', {1,2})
|
||||
expect_err('Not a function: f', request,
|
||||
expect_err('Not a function: f$', request,
|
||||
'nvim_call_dict_function', "{ 'f': '' }", 'f', {1,2})
|
||||
expect_err('dict argument type must be String or Dictionary', request,
|
||||
expect_err('dict argument type must be String or Dictionary$', request,
|
||||
'nvim_call_dict_function', 42, 'f', {1,2})
|
||||
expect_err('Failed to evaluate dict expression', request,
|
||||
expect_err('Failed to evaluate dict expression$', request,
|
||||
'nvim_call_dict_function', 'foo', 'f', {1,2})
|
||||
expect_err('dict not found', request,
|
||||
expect_err('dict not found$', request,
|
||||
'nvim_call_dict_function', '42', 'f', {1,2})
|
||||
expect_err('Invalid %(empty%) function name', request,
|
||||
expect_err('Invalid %(empty%) function name$', request,
|
||||
'nvim_call_dict_function', "{ 'f': '' }", '', {1,2})
|
||||
end)
|
||||
end)
|
||||
@ -337,7 +349,7 @@ describe('API', function()
|
||||
eq(1, funcs.exists('g:lua'))
|
||||
meths.del_var('lua')
|
||||
eq(0, funcs.exists('g:lua'))
|
||||
eq({false, 'Key does not exist: lua'}, meth_pcall(meths.del_var, 'lua'))
|
||||
eq({false, "Key not found: lua"}, meth_pcall(meths.del_var, 'lua'))
|
||||
meths.set_var('lua', 1)
|
||||
command('lockvar lua')
|
||||
eq({false, 'Key is locked: lua'}, meth_pcall(meths.del_var, 'lua'))
|
||||
@ -948,7 +960,7 @@ describe('API', function()
|
||||
}
|
||||
local status, err = pcall(meths.call_atomic, req)
|
||||
eq(false, status)
|
||||
ok(err:match(' All items in calls array must be arrays of size 2') ~= nil)
|
||||
ok(err:match('Items in calls array must be arrays of size 2') ~= nil)
|
||||
-- call before was done, but not after
|
||||
eq(1, meths.get_var('avar'))
|
||||
|
||||
@ -958,7 +970,7 @@ describe('API', function()
|
||||
}
|
||||
status, err = pcall(meths.call_atomic, req)
|
||||
eq(false, status)
|
||||
ok(err:match('All items in calls array must be arrays') ~= nil)
|
||||
ok(err:match('Items in calls array must be arrays') ~= nil)
|
||||
eq({2,3}, meths.get_var('bvar'))
|
||||
|
||||
req = {
|
||||
|
@ -169,7 +169,7 @@ describe('api/win', function()
|
||||
eq(1, funcs.exists('w:lua'))
|
||||
curwinmeths.del_var('lua')
|
||||
eq(0, funcs.exists('w:lua'))
|
||||
eq({false, 'Key does not exist: lua'}, meth_pcall(curwinmeths.del_var, 'lua'))
|
||||
eq({false, 'Key not found: lua'}, meth_pcall(curwinmeths.del_var, 'lua'))
|
||||
curwinmeths.set_var('lua', 1)
|
||||
command('lockvar w:lua')
|
||||
eq({false, 'Key is locked: lua'}, meth_pcall(curwinmeths.del_var, 'lua'))
|
||||
|
Loading…
Reference in New Issue
Block a user