mirror of
https://github.com/neovim/neovim.git
synced 2026-07-09 10:59:38 +00:00
fix(autocmd): safely parse buflocal buffer numbers (#40436)
* refactor(autocmd): safely parse buflocal buffer numbers Replace unsafe atoi with a robust integer conversion when extracting the buffer number out of a "<buffer=123>" pattern in aupat\_get\_buflocal\_nr. This prevents potential silent integer overflows and ensures variables fit safely within INT\_MAX boundaries before truncation. * fix(autocmd): use getdigits_int to safely parse buffer numbers * fix(autocmd): raise error for invalid buffer-local pattern values When defining an autocommand, an invalid buffer-local pattern format (such as `<buffer=foo>` or `<buffer=0>`) would previously fall through silently and default to a generic `<buffer>` tag behavior. Fix this regression by trapping invalid buffer numbers early from `aupat_get_buflocal_nr()` and throwing a proper E680 error to match Vim's runtime validation behavior.
This commit is contained in:
committed by
GitHub
parent
cef31fde6a
commit
35cbf4fbdd
@@ -931,6 +931,10 @@ int do_autocmd_event(event_T event, const char *pat, bool once, int nested, cons
|
||||
if (is_buflocal) {
|
||||
const int buflocal_nr = aupat_get_buflocal_nr(pat, patlen);
|
||||
|
||||
if (buflocal_nr == 0 || buflist_findnr(buflocal_nr) == NULL) {
|
||||
semsg(_(e_buffer_nr_invalid_buffer_number), buflocal_nr);
|
||||
return FAIL;
|
||||
}
|
||||
// normalize pat into standard "<buffer>#N" form
|
||||
aupat_normalize_buflocal_pat(buflocal_pat, pat, patlen, buflocal_nr);
|
||||
|
||||
@@ -1000,6 +1004,10 @@ int autocmd_register(int64_t id, event_T event, const char *pat, int patlen, int
|
||||
if (is_buflocal) {
|
||||
buflocal_nr = aupat_get_buflocal_nr(pat, patlen);
|
||||
|
||||
if (buflocal_nr == 0 || buflist_findnr(buflocal_nr) == NULL) {
|
||||
semsg(_(e_buffer_nr_invalid_buffer_number), buflocal_nr);
|
||||
return FAIL;
|
||||
}
|
||||
// normalize pat into standard "<buffer>#N" form
|
||||
aupat_normalize_buflocal_pat(buflocal_pat, pat, patlen, buflocal_nr);
|
||||
|
||||
@@ -1025,12 +1033,6 @@ int autocmd_register(int64_t id, event_T event, const char *pat, int patlen, int
|
||||
|
||||
// No matching pattern found, allocate a new one.
|
||||
if (ap == NULL) {
|
||||
// refuse to add buffer-local ap if buffer number is invalid
|
||||
if (is_buflocal && (buflocal_nr == 0 || buflist_findnr(buflocal_nr) == NULL)) {
|
||||
semsg(_("E680: <buffer=%d>: invalid buffer number "), buflocal_nr);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
ap = xmalloc(sizeof(AutoPat));
|
||||
|
||||
if (is_buflocal) {
|
||||
@@ -2592,7 +2594,8 @@ int aupat_get_buflocal_nr(const char *pat, int patlen)
|
||||
|
||||
// "<buffer=123>"
|
||||
if (skipdigits(pat + 8) == pat + patlen - 1) {
|
||||
return atoi(pat + 8);
|
||||
char *p = (char *)pat + 8;
|
||||
return getdigits_int(&p, false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ EXTERN const char e_cmdwin[] INIT(= N_("E11: Invalid in command-line window; <CR
|
||||
EXTERN const char e_curdir[] INIT(= N_("E12: Command not allowed in secure mode in current dir or tag search"));
|
||||
EXTERN const char e_invalid_buffer_name_str[] INIT(= N_("E158: Invalid buffer name: %s"));
|
||||
EXTERN const char e_command_too_recursive[] INIT(= N_("E169: Command too recursive"));
|
||||
EXTERN const char e_buffer_nr_invalid_buffer_number[] INIT(= N_("E680: <buffer=%d>: invalid buffer number"));
|
||||
EXTERN const char e_buffer_is_not_loaded[] INIT(= N_("E681: Buffer is not loaded"));
|
||||
EXTERN const char e_endif[] INIT(= N_("E171: Missing :endif"));
|
||||
EXTERN const char e_endtry[] INIT(= N_("E600: Missing :endtry"));
|
||||
|
||||
Reference in New Issue
Block a user