mirror of
https://github.com/neovim/neovim.git
synced 2026-11-06 05:16:52 +00:00
fix(ui2): bogus "'replacement string' item" message #42650
Problem: UI event handlers may clobber `IObuff` while the caller is using it. With ui2 `targets='msg'`, `i_CTRL-O :edit` shows "'replacement string' item" instead of the file info, because `check_string_array()` writes `IObuff` on every `nvim_buf_set_lines()`. Solution: - Save and restore `IObuff` around UI event handlers. This is 1KB, but negligible vs the other work that UI handlers do (msgpack, Lua calls). - `check_string_array()`: don't use `IObuff`.
This commit is contained in:
1 parent
13f4c205e1
commit
124a28de97
3 files changed
+23
-5
No files matched your search
@@ -1,12 +1,10 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nvim/api/private/defs.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/api/private/validate.h"
|
||||
#include "nvim/ascii_defs.h"
|
||||
#include "nvim/globals.h"
|
||||
|
||||
/// Creates "Invalid …" message and sets it on `err`.
|
||||
void api_err_invalid(Error *err, const char *name, const char *val_s, int64_t val_n, bool quote_val)
|
||||
@@ -84,11 +82,12 @@ void api_err_conflict(Error *err, const char *name, const char *name2)
|
||||
|
||||
bool check_string_array(Array arr, char *name, bool disallow_nl, Error *err)
|
||||
{
|
||||
snprintf(IObuff, sizeof(IObuff), "'%s' item", name);
|
||||
for (size_t i = 0; i < arr.size; i++) {
|
||||
VALIDATE_T(IObuff, kObjectTypeString, arr.items[i].type, {
|
||||
if (arr.items[i].type != kObjectTypeString) {
|
||||
api_set_error(err, kErrorTypeValidation, "Invalid '%s' item: expected String, got %s", name,
|
||||
api_typename(arr.items[i].type));
|
||||
return false;
|
||||
});
|
||||
}
|
||||
// Disallow newlines in the middle of the line.
|
||||
if (disallow_nl) {
|
||||
const String l = arr.items[i].data.string;
|
||||
|
||||
@@ -797,6 +797,9 @@ void ui_call_event(char *name, Array args)
|
||||
int save_textlock = textlock;
|
||||
expr_map_lock = 0;
|
||||
textlock = 0;
|
||||
// Caller may still be using `IObuff`, e.g. as the message being shown.
|
||||
char save_iobuff[IOSIZE];
|
||||
memcpy(save_iobuff, IObuff, IOSIZE);
|
||||
|
||||
bool handled = false;
|
||||
bool fast = msg_ext_fast && strcmp("msg_show", name) == 0;
|
||||
@@ -818,6 +821,7 @@ void ui_call_event(char *name, Array args)
|
||||
|
||||
expr_map_lock = save_expr_map_lock;
|
||||
textlock = save_textlock;
|
||||
memcpy(IObuff, save_iobuff, IOSIZE);
|
||||
ctx_load(&ctx, kCtxCount, 0);
|
||||
ctx_free(&ctx);
|
||||
|
||||
|
||||
@@ -1196,6 +1196,21 @@ describe('messages2', function()
|
||||
end)
|
||||
feed('2gm')
|
||||
t.eq(2, exec_lua('return _G.count'))
|
||||
|
||||
-- Handler does not clobber the file info message, which is repeated after `i_CTRL-O`.
|
||||
finally(function()
|
||||
os.remove('Xfile')
|
||||
end)
|
||||
t.write_file('Xfile', '')
|
||||
command('set messagesopt& shortmess-=F | edit Xfile')
|
||||
feed('i<C-o>:edit<CR>')
|
||||
screen:expect([[
|
||||
^ |
|
||||
{1:~ }|*10
|
||||
{1:~ }{4:"Xfile" "Xfile" }|
|
||||
{1:~ }{4:"Xfile" 0L, 0B(1)}|
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('configured targets per kind', function()
|
||||
|
||||
Reference in new issue
Block a user