fix(autocmd): API functions accept garbage after event name #25523

"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.

Co-authored-by: ii14 <ii14@users.noreply.github.com>
This commit is contained in:
ii14 2023-10-09 11:50:44 +02:00 committed by GitHub
parent 8e932480f6
commit 139e6f68f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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.
// Get the event number, unless it is an error. Then goto `goto_name`.
#define GET_ONE_EVENT(event_nr, event_str, goto_name) \
char *__next_ev; \
event_T event_nr = \
event_name2nr(event_str.data.string.data, &__next_ev); \
if (event_nr >= NUM_EVENTS) { \
api_set_error(err, kErrorTypeValidation, "unexpected event"); \
event_name2nr_str(event_str.data.string); \
VALIDATE_S((event_nr < NUM_EVENTS), "event", event_str.data.string.data, { \
goto goto_name; \
}
});
// ID for associating autocmds created via nvim_create_autocmd
// Used to delete autocmds from nvim_del_autocmd

View File

@ -597,9 +597,9 @@ bool is_aucmd_win(win_T *win)
return false;
}
// Return the event number for event name "start".
// Return NUM_EVENTS if the event name was not found.
// Return a pointer to the next event name in "end".
/// Return the event number for event name "start".
/// Return NUM_EVENTS if the event name was not found.
/// Return a pointer to the next event name in "end".
event_T event_name2nr(const char *start, char **end)
{
const char *p;
@ -623,6 +623,18 @@ event_T event_name2nr(const char *start, char **end)
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
///
/// @param[in] event Event to return name for.

View File

@ -43,6 +43,11 @@ describe('autocmd api', function()
group = 0,
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)
it('doesnt leak when you use ++once', function()