diff options
author | Lewis Russell <lewis6991@gmail.com> | 2023-04-27 17:30:22 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-27 17:30:22 +0100 |
commit | eb4676c67f5dd54bcda473783315901a3444b40b (patch) | |
tree | b57dd8342e3de756031664188ab542ead9134c38 /src/nvim/api | |
parent | 9f29176033926b81553985deaba0ea162ca40215 (diff) | |
download | rneovim-eb4676c67f5dd54bcda473783315901a3444b40b.tar.gz rneovim-eb4676c67f5dd54bcda473783315901a3444b40b.tar.bz2 rneovim-eb4676c67f5dd54bcda473783315901a3444b40b.zip |
fix: disallow removing extmarks in on_lines callbacks (#23219)
fix(extmarks): disallow removing extmarks in on_lines callbacks
decor_redraw_start (which runs before decor_providers_invoke_lines) gets
references for the extmarks on a specific line. If these extmarks are
deleted in on_lines callbacks then this results in a heap-use-after-free
error.
Fixes #22801
Diffstat (limited to 'src/nvim/api')
-rw-r--r-- | src/nvim/api/deprecated.c | 2 | ||||
-rw-r--r-- | src/nvim/api/extmark.c | 21 |
2 files changed, 19 insertions, 4 deletions
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index 5937b2f635..0ca505e7b2 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -172,7 +172,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A decor.priority = 0; extmark_set(buf, ns_id, NULL, (int)line, 0, -1, -1, &decor, true, - false, kExtmarkNoUndo); + false, kExtmarkNoUndo, NULL); return src_id; } diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index b781da1dc3..87232a8a93 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -874,7 +874,10 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer extmark_set(buf, (uint32_t)ns_id, &id, (int)line, (colnr_T)col, line2, col2, has_decor ? &decor : NULL, right_gravity, end_right_gravity, - kExtmarkNoUndo); + kExtmarkNoUndo, err); + if (ERROR_SET(err)) { + goto error; + } } return (Integer)id; @@ -903,6 +906,11 @@ Boolean nvim_buf_del_extmark(Buffer buffer, Integer ns_id, Integer id, Error *er return false; }); + if (decor_state.running_on_lines) { + api_set_error(err, kErrorTypeValidation, "Cannot remove extmarks during on_line callbacks"); + return false; + } + return extmark_del(buf, (uint32_t)ns_id, (uint32_t)id); } @@ -993,7 +1001,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, In extmark_set(buf, ns, NULL, (int)line, (colnr_T)col_start, end_line, (colnr_T)col_end, - &decor, true, false, kExtmarkNoUndo); + &decor, true, false, kExtmarkNoUndo, NULL); return ns_id; } @@ -1022,6 +1030,11 @@ void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start, return; }); + if (decor_state.running_on_lines) { + api_set_error(err, kErrorTypeValidation, "Cannot remove extmarks during on_line callbacks"); + return; + } + if (line_end < 0 || line_end > MAXLNUM) { line_end = MAXLNUM; } @@ -1051,11 +1064,13 @@ void nvim_buf_clear_namespace(Buffer buffer, Integer ns_id, Integer line_start, /// for the extmarks set/modified inside the callback anyway. /// /// Note: doing anything other than setting extmarks is considered experimental. -/// Doing things like changing options are not expliticly forbidden, but is +/// Doing things like changing options are not explicitly forbidden, but is /// likely to have unexpected consequences (such as 100% CPU consumption). /// doing `vim.rpcnotify` should be OK, but `vim.rpcrequest` is quite dubious /// for the moment. /// +/// Note: It is not allowed to remove or update extmarks in 'on_line' callbacks. +/// /// @param ns_id Namespace id from |nvim_create_namespace()| /// @param opts Table of callbacks: /// - on_start: called first on each screen redraw |