fix(autocmd): api functions accepting garbage after event name

"VimEnter foo" was accepted as a valid event name for "VimEnter".
Events delimited with commas, eg. "VimEnter,BufRead", were also
accepted, even though only the first event was actually parsed.

(cherry picked from commit 1397016259)
This commit is contained in:
ii14
2023-10-06 14:34:22 +02:00
committed by Christian Clason
parent 2bde3109b8
commit eddead1cad
3 changed files with 23 additions and 8 deletions

View File

@@ -33,13 +33,11 @@
// Copy string or array of strings into an empty array. // Copy string or array of strings into an empty array.
// Get the event number, unless it is an error. Then goto `goto_name`. // Get the event number, unless it is an error. Then goto `goto_name`.
#define GET_ONE_EVENT(event_nr, event_str, goto_name) \ #define GET_ONE_EVENT(event_nr, event_str, goto_name) \
char *__next_ev; \
event_T event_nr = \ event_T event_nr = \
event_name2nr(event_str.data.string.data, &__next_ev); \ event_name2nr_str(event_str.data.string); \
if (event_nr >= NUM_EVENTS) { \ VALIDATE_S((event_nr < NUM_EVENTS), "event", event_str.data.string.data, { \
api_set_error(err, kErrorTypeValidation, "unexpected event"); \
goto goto_name; \ goto goto_name; \
} });
// ID for associating autocmds created via nvim_create_autocmd // ID for associating autocmds created via nvim_create_autocmd
// Used to delete autocmds from nvim_del_autocmd // Used to delete autocmds from nvim_del_autocmd

View File

@@ -675,9 +675,9 @@ bool is_aucmd_win(win_T *win)
return false; return false;
} }
// Return the event number for event name "start". /// Return the event number for event name "start".
// Return NUM_EVENTS if the event name was not found. /// Return NUM_EVENTS if the event name was not found.
// Return a pointer to the next event name in "end". /// Return a pointer to the next event name in "end".
event_T event_name2nr(const char *start, char **end) event_T event_name2nr(const char *start, char **end)
{ {
const char *p; const char *p;
@@ -701,6 +701,18 @@ event_T event_name2nr(const char *start, char **end)
return event_names[i].event; return event_names[i].event;
} }
/// Return the event number for event name "str".
/// Return NUM_EVENTS if the event name was not found.
event_T event_name2nr_str(String str)
{
for (int i = 0; event_names[i].name != NULL; i++) {
if (str.size == event_names[i].len && STRNICMP(str.data, event_names[i].name, str.size) == 0) {
return event_names[i].event;
}
}
return NUM_EVENTS;
}
/// Return the name for event /// Return the name for event
/// ///
/// @param[in] event Event to return name for. /// @param[in] event Event to return name for.

View File

@@ -43,6 +43,11 @@ describe('autocmd api', function()
group = 0, group = 0,
command = 'ls', command = 'ls',
})) }))
eq("Invalid 'event': 'foo'", pcall_err(meths.create_autocmd, 'foo', { command = '' }))
eq("Invalid 'event': 'VimEnter '", pcall_err(meths.create_autocmd, 'VimEnter ', { command = '' }))
eq("Invalid 'event': 'VimEnter foo'", pcall_err(meths.create_autocmd, 'VimEnter foo', { command = '' }))
eq("Invalid 'event': 'BufAdd,BufDelete'", pcall_err(meths.create_autocmd, 'BufAdd,BufDelete', { command = '' }))
end) end)
it('doesnt leak when you use ++once', function() it('doesnt leak when you use ++once', function()