diff options
Diffstat (limited to 'src/nvim')
-rw-r--r-- | src/nvim/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/nvim/README.md | 3 | ||||
-rw-r--r-- | src/nvim/buffer.c | 6 | ||||
-rw-r--r-- | src/nvim/bufwrite.c | 16 | ||||
-rw-r--r-- | src/nvim/cmdhist.c | 7 | ||||
-rw-r--r-- | src/nvim/eval/userfunc.c | 6 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 8 | ||||
-rw-r--r-- | src/nvim/fileio.c | 27 | ||||
-rw-r--r-- | src/nvim/lua/treesitter.c | 89 | ||||
-rw-r--r-- | src/nvim/main.c | 14 | ||||
-rw-r--r-- | src/nvim/move.c | 4 | ||||
-rw-r--r-- | src/nvim/option.c | 2 | ||||
-rw-r--r-- | src/nvim/os/stdpaths.c | 2 | ||||
-rw-r--r-- | src/nvim/runtime.c | 2 | ||||
-rw-r--r-- | src/nvim/tag.c | 2 | ||||
-rw-r--r-- | src/nvim/testing.c | 4 | ||||
-rw-r--r-- | src/nvim/textobject.c | 3 | ||||
-rw-r--r-- | src/nvim/undo.c | 2 |
18 files changed, 152 insertions, 46 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 325b376b30..070cea3b59 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -836,6 +836,7 @@ if(ENABLE_ASAN_UBSAN) -fsanitize=address -fsanitize=undefined) target_link_libraries(nvim PRIVATE -fsanitize=address -fsanitize=undefined) + target_compile_definitions(nvim PRIVATE ENABLE_ASAN_UBSAN) elseif(ENABLE_MSAN) message(STATUS "Enabling memory sanitizer for nvim.") target_compile_options(nvim PRIVATE diff --git a/src/nvim/README.md b/src/nvim/README.md index cbd5daba4e..75155fb9c6 100644 --- a/src/nvim/README.md +++ b/src/nvim/README.md @@ -71,9 +71,8 @@ Create a directory to store logs: Configure the sanitizer(s) via these environment variables: # Change to detect_leaks=1 to detect memory leaks (slower, noisier). - export ASAN_OPTIONS="detect_leaks=0:log_path=$HOME/logs/asan,handle_abort=1,handle_sigill=1" + export ASAN_OPTIONS="detect_leaks=0:log_path=$HOME/logs/asan" # Show backtraces in the logs. - export UBSAN_OPTIONS=print_stacktrace=1 export MSAN_OPTIONS="log_path=${HOME}/logs/msan" export TSAN_OPTIONS="log_path=${HOME}/logs/tsan" diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index e734a340d9..49fd09ebd0 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1084,11 +1084,11 @@ char *do_bufdel(int command, char *arg, int addr_count, int start_bnr, int end_b if (deleted == 0) { if (command == DOBUF_UNLOAD) { - STRCPY(IObuff, _("E515: No buffers were unloaded")); + xstrlcpy(IObuff, _("E515: No buffers were unloaded"), IOSIZE); } else if (command == DOBUF_DEL) { - STRCPY(IObuff, _("E516: No buffers were deleted")); + xstrlcpy(IObuff, _("E516: No buffers were deleted"), IOSIZE); } else { - STRCPY(IObuff, _("E517: No buffers were wiped out")); + xstrlcpy(IObuff, _("E517: No buffers were wiped out"), IOSIZE); } errormsg = IObuff; } else if (deleted >= p_report) { diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c index 84c1276b8b..cfa3ea5bf3 100644 --- a/src/nvim/bufwrite.c +++ b/src/nvim/bufwrite.c @@ -745,7 +745,7 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o // the ones from the original file. // First find a file name that doesn't exist yet (use some // arbitrary numbers). - STRCPY(IObuff, fname); + xstrlcpy(IObuff, fname, IOSIZE); for (int i = 4913;; i += 123) { char *tail = path_tail(IObuff); size_t size = (size_t)(tail - IObuff); @@ -1749,24 +1749,24 @@ restore_backup: add_quoted_fname(IObuff, IOSIZE, buf, fname); bool insert_space = false; if (write_info.bw_conv_error) { - STRCAT(IObuff, _(" CONVERSION ERROR")); + xstrlcat(IObuff, _(" CONVERSION ERROR"), IOSIZE); insert_space = true; if (write_info.bw_conv_error_lnum != 0) { vim_snprintf_add(IObuff, IOSIZE, _(" in line %" PRId64 ";"), (int64_t)write_info.bw_conv_error_lnum); } } else if (notconverted) { - STRCAT(IObuff, _("[NOT converted]")); + xstrlcat(IObuff, _("[NOT converted]"), IOSIZE); insert_space = true; } else if (converted) { - STRCAT(IObuff, _("[converted]")); + xstrlcat(IObuff, _("[converted]"), IOSIZE); insert_space = true; } if (device) { - STRCAT(IObuff, _("[Device]")); + xstrlcat(IObuff, _("[Device]"), IOSIZE); insert_space = true; } else if (newfile) { - STRCAT(IObuff, new_file_message()); + xstrlcat(IObuff, new_file_message(), IOSIZE); insert_space = true; } if (no_eol) { @@ -1780,9 +1780,9 @@ restore_backup: msg_add_lines(insert_space, (long)lnum, nchars); // add line/char count if (!shortmess(SHM_WRITE)) { if (append) { - STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended")); + xstrlcat(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended"), IOSIZE); } else { - STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written")); + xstrlcat(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written"), IOSIZE); } } diff --git a/src/nvim/cmdhist.c b/src/nvim/cmdhist.c index 81b93e5304..fc84cecc1a 100644 --- a/src/nvim/cmdhist.c +++ b/src/nvim/cmdhist.c @@ -641,9 +641,10 @@ void ex_history(exarg_T *eap) } for (; !got_int && histype1 <= histype2; histype1++) { - STRCPY(IObuff, "\n # "); + xstrlcpy(IObuff, "\n # ", IOSIZE); assert(history_names[histype1] != NULL); - STRCAT(STRCAT(IObuff, history_names[histype1]), " history"); + xstrlcat(IObuff, history_names[histype1], IOSIZE); + xstrlcat(IObuff, " history", IOSIZE); msg_puts_title(IObuff); int idx = hisidx[histype1]; histentry_T *hist = history[histype1]; @@ -669,7 +670,7 @@ void ex_history(exarg_T *eap) trunc_string(hist[i].hisstr, IObuff + strlen(IObuff), Columns - 10, IOSIZE - (int)strlen(IObuff)); } else { - STRCAT(IObuff, hist[i].hisstr); + xstrlcat(IObuff, hist[i].hisstr, IOSIZE); } msg_outtrans(IObuff); } diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 7e20a298dd..a52b8d3f18 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -2892,9 +2892,9 @@ char *get_user_func_name(expand_T *xp, int idx) cat_func_name(IObuff, IOSIZE, fp); if (xp->xp_context != EXPAND_USER_FUNC) { - STRCAT(IObuff, "("); + xstrlcat(IObuff, "(", IOSIZE); if (!fp->uf_varargs && GA_EMPTY(&fp->uf_args)) { - STRCAT(IObuff, ")"); + xstrlcat(IObuff, ")", IOSIZE); } } return IObuff; @@ -3505,7 +3505,7 @@ char *get_return_cmd(void *rettv) s = ""; } - STRCPY(IObuff, ":return "); + xstrlcpy(IObuff, ":return ", IOSIZE); xstrlcpy(IObuff + 8, s, IOSIZE - 8); if (strlen(s) + 8 >= IOSIZE) { STRCPY(IObuff + IOSIZE - 4, "..."); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 83232d5f17..9666d80de2 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1454,7 +1454,7 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er } // Fail if command is invalid if (eap->cmdidx == CMD_SIZE) { - STRCPY(IObuff, _(e_not_an_editor_command)); + xstrlcpy(IObuff, _(e_not_an_editor_command), IOSIZE); // If the modifier was parsed OK the error must be in the following command char *cmdname = after_modifier ? after_modifier : cmdline; append_command(cmdname); @@ -2044,7 +2044,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter // Check for wrong commands. if (ea.cmdidx == CMD_SIZE) { if (!ea.skip) { - STRCPY(IObuff, _(e_not_an_editor_command)); + xstrlcpy(IObuff, _(e_not_an_editor_command), IOSIZE); // If the modifier was parsed OK the error must be in the following // command char *cmdname = after_modifier ? after_modifier : *cmdlinep; @@ -2321,7 +2321,7 @@ doend: if (errormsg != NULL && *errormsg != NUL && !did_emsg) { if (flags & DOCMD_VERBOSE) { if (errormsg != IObuff) { - STRCPY(IObuff, errormsg); + xstrlcpy(IObuff, errormsg, IOSIZE); errormsg = IObuff; } append_command(*ea.cmdlinep); @@ -2888,7 +2888,7 @@ static void append_command(char *cmd) d -= utf_head_off(IObuff, d); STRCPY(d, "..."); } - STRCAT(IObuff, ": "); + xstrlcat(IObuff, ": ", IOSIZE); d = IObuff + strlen(IObuff); while (*s != NUL && d - IObuff + 5 < IOSIZE) { if ((uint8_t)s[0] == 0xc2 && (uint8_t)s[1] == 0xa0) { diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index d659987686..57aa063504 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -1693,22 +1693,22 @@ failed: #ifdef UNIX if (S_ISFIFO(perm)) { // fifo - STRCAT(IObuff, _("[fifo]")); + xstrlcat(IObuff, _("[fifo]"), IOSIZE); c = true; } if (S_ISSOCK(perm)) { // or socket - STRCAT(IObuff, _("[socket]")); + xstrlcat(IObuff, _("[socket]"), IOSIZE); c = true; } # ifdef OPEN_CHR_FILES if (S_ISCHR(perm)) { // or character special - STRCAT(IObuff, _("[character special]")); + xstrlcat(IObuff, _("[character special]"), IOSIZE); c = true; } # endif #endif if (curbuf->b_p_ro) { - STRCAT(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]")); + xstrlcat(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]"), IOSIZE); c = true; } if (read_no_eol_lnum) { @@ -1716,18 +1716,18 @@ failed: c = true; } if (ff_error == EOL_DOS) { - STRCAT(IObuff, _("[CR missing]")); + xstrlcat(IObuff, _("[CR missing]"), IOSIZE); c = true; } if (split) { - STRCAT(IObuff, _("[long lines split]")); + xstrlcat(IObuff, _("[long lines split]"), IOSIZE); c = true; } if (notconverted) { - STRCAT(IObuff, _("[NOT converted]")); + xstrlcat(IObuff, _("[NOT converted]"), IOSIZE); c = true; } else if (converted) { - STRCAT(IObuff, _("[converted]")); + xstrlcat(IObuff, _("[converted]"), IOSIZE); c = true; } if (conv_error != 0) { @@ -1739,7 +1739,7 @@ failed: _("[ILLEGAL BYTE in line %" PRId64 "]"), (int64_t)illegal_byte); c = true; } else if (error) { - STRCAT(IObuff, _("[READ ERRORS]")); + xstrlcat(IObuff, _("[READ ERRORS]"), IOSIZE); c = true; } if (msg_add_fileformat(fileformat)) { @@ -2128,17 +2128,17 @@ bool msg_add_fileformat(int eol_type) { #ifndef USE_CRNL if (eol_type == EOL_DOS) { - STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[dos]") : _("[dos format]")); + xstrlcat(IObuff, shortmess(SHM_TEXT) ? _("[dos]") : _("[dos format]"), IOSIZE); return true; } #endif if (eol_type == EOL_MAC) { - STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[mac]") : _("[mac format]")); + xstrlcat(IObuff, shortmess(SHM_TEXT) ? _("[mac]") : _("[mac format]"), IOSIZE); return true; } #ifdef USE_CRNL if (eol_type == EOL_UNIX) { - STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[unix]") : _("[unix format]")); + xstrlcat(IObuff, shortmess(SHM_TEXT) ? _("[unix]") : _("[unix format]"), IOSIZE); return true; } #endif @@ -2170,8 +2170,7 @@ void msg_add_lines(int insert_space, long lnum, off_T nchars) /// Append message for missing line separator to IObuff. void msg_add_eol(void) { - STRCAT(IObuff, - shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]")); + xstrlcat(IObuff, shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"), IOSIZE); } bool time_differs(const FileInfo *file_info, long mtime, long mtime_ns) FUNC_ATTR_CONST diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c index dae1365272..a9e7838980 100644 --- a/src/nvim/lua/treesitter.c +++ b/src/nvim/lua/treesitter.c @@ -20,6 +20,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/buffer_defs.h" #include "nvim/globals.h" +#include "nvim/lua/executor.h" #include "nvim/lua/treesitter.h" #include "nvim/macros.h" #include "nvim/map.h" @@ -43,6 +44,13 @@ typedef struct { int max_match_id; } TSLua_cursor; +typedef struct { + LuaRef cb; + lua_State *lstate; + bool lex; + bool parse; +} TSLuaLoggerOpts; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "lua/treesitter.c.generated.h" #endif @@ -56,6 +64,8 @@ static struct luaL_Reg parser_meta[] = { { "included_ranges", parser_get_ranges }, { "set_timeout", parser_set_timeout }, { "timeout", parser_get_timeout }, + { "_set_logger", parser_set_logger }, + { "_logger", parser_get_logger }, { NULL, NULL } }; @@ -322,6 +332,12 @@ static int parser_gc(lua_State *L) return 0; } + TSLogger logger = ts_parser_logger(*p); + if (logger.log) { + TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)logger.payload; + xfree(opts); + } + ts_parser_delete(*p); return 0; } @@ -669,9 +685,82 @@ static int parser_get_timeout(lua_State *L) } lua_pushinteger(L, (long)ts_parser_timeout_micros(*p)); + return 1; +} + +static void logger_cb(void *payload, TSLogType logtype, const char *s) +{ + TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)payload; + if ((!opts->lex && logtype == TSLogTypeLex) + || (!opts->parse && logtype == TSLogTypeParse)) { + return; + } + + lua_State *lstate = opts->lstate; + + nlua_pushref(lstate, opts->cb); + lua_pushstring(lstate, logtype == TSLogTypeParse ? "parse" : "lex"); + lua_pushstring(lstate, s); + if (lua_pcall(lstate, 2, 0, 0)) { + luaL_error(lstate, "Error executing treesitter logger callback"); + } +} + +static int parser_set_logger(lua_State *L) +{ + TSParser **p = parser_check(L, 1); + if (!p) { + return 0; + } + + if (!lua_isboolean(L, 2)) { + return luaL_argerror(L, 2, "boolean expected"); + } + + if (!lua_isboolean(L, 3)) { + return luaL_argerror(L, 3, "boolean expected"); + } + + if (!lua_isfunction(L, 4)) { + return luaL_argerror(L, 4, "function expected"); + } + + TSLuaLoggerOpts *opts = xmalloc(sizeof(TSLuaLoggerOpts)); + + *opts = (TSLuaLoggerOpts){ + .lex = lua_toboolean(L, 2), + .parse = lua_toboolean(L, 3), + .cb = nlua_ref_global(L, 4), + .lstate = L + }; + + TSLogger logger = { + .payload = (void *)opts, + .log = logger_cb + }; + + ts_parser_set_logger(*p, logger); return 0; } +static int parser_get_logger(lua_State *L) +{ + TSParser **p = parser_check(L, 1); + if (!p) { + return 0; + } + + TSLogger logger = ts_parser_logger(*p); + if (logger.log) { + TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)logger.payload; + nlua_pushref(L, opts->cb); + } else { + lua_pushnil(L); + } + + return 1; +} + // Tree methods /// push tree interface on lua stack. diff --git a/src/nvim/main.c b/src/nvim/main.c index 659eccc6f0..4999d9dd2a 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -2222,3 +2222,17 @@ static void check_swap_exists_action(void) } handle_swap_exists(NULL); } + +#ifdef ENABLE_ASAN_UBSAN +const char *__ubsan_default_options(void); +const char *__ubsan_default_options(void) +{ + return "print_stacktrace=1"; +} + +const char *__asan_default_options(void); +const char *__asan_default_options(void) +{ + return "handle_abort=1,handle_sigill=1"; +} +#endif diff --git a/src/nvim/move.c b/src/nvim/move.c index 6a6f8149dd..ead2b3b0d3 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -1502,11 +1502,11 @@ void adjust_skipcol(void) } else { curwin->w_skipcol -= width1; } - redraw_later(curwin, UPD_NOT_VALID); scrolled = true; - validate_virtcol(); } if (scrolled) { + validate_virtcol(); + redraw_later(curwin, UPD_NOT_VALID); return; // don't scroll in the other direction now } long col = curwin->w_virtcol - curwin->w_skipcol + scrolloff_cols; diff --git a/src/nvim/option.c b/src/nvim/option.c index fc1fc87b62..327c5fc089 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1626,7 +1626,7 @@ int do_set(char *arg, int opt_flags) int i = (int)strlen(IObuff) + 2; if (i + (arg - startarg) < IOSIZE) { // append the argument with the error - STRCAT(IObuff, ": "); + xstrlcat(IObuff, ": ", IOSIZE); assert(arg >= startarg); memmove(IObuff + i, startarg, (size_t)(arg - startarg)); IObuff[i + (arg - startarg)] = NUL; diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 5235828f7a..8b62b9e895 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -130,7 +130,7 @@ char *get_xdg_home(const XDGVarType idx) xstrlcpy(IObuff, appname, appname_len + 1); #if defined(MSWIN) if (idx == kXDGDataHome || idx == kXDGStateHome) { - STRCAT(IObuff, "-data"); + xstrlcat(IObuff, "-data", IOSIZE); } #endif dir = concat_fnames_realloc(dir, IObuff, true); diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index f7b7723553..a9068fabc8 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1544,7 +1544,7 @@ static inline char *add_dir(char *dest, const char *const dir, const size_t dir_ xstrlcpy(IObuff, appname, appname_len + 1); #if defined(MSWIN) if (type == kXDGDataHome || type == kXDGStateHome) { - STRCAT(IObuff, "-data"); + xstrlcat(IObuff, "-data", IOSIZE); appname_len += 5; } #endif diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 81bca67cf7..18331cc95d 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -732,7 +732,7 @@ void do_tag(char *tag, int type, int count, int forceit, int verbose) num_matches, max_num_matches != MAXCOL ? _(" or more") : ""); if (ic) { - STRCAT(IObuff, _(" Using tag with different case!")); + xstrlcat(IObuff, _(" Using tag with different case!"), IOSIZE); } if ((num_matches > prev_num_matches || new_tag) && num_matches > 1) { diff --git a/src/nvim/testing.c b/src/nvim/testing.c index 5483a58525..25ec8e898a 100644 --- a/src/nvim/testing.c +++ b/src/nvim/testing.c @@ -418,11 +418,11 @@ static int assert_equalfile(typval_T *argvars) const int c2 = fgetc(fd2); if (c1 == EOF) { if (c2 != EOF) { - STRCPY(IObuff, "first file is shorter"); + xstrlcpy(IObuff, "first file is shorter", IOSIZE); } break; } else if (c2 == EOF) { - STRCPY(IObuff, "second file is shorter"); + xstrlcpy(IObuff, "second file is shorter", IOSIZE); break; } else { line1[lineidx] = (char)c1; diff --git a/src/nvim/textobject.c b/src/nvim/textobject.c index 428b14a68d..5036c10827 100644 --- a/src/nvim/textobject.c +++ b/src/nvim/textobject.c @@ -22,6 +22,7 @@ #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" +#include "nvim/move.h" #include "nvim/normal.h" #include "nvim/option_defs.h" #include "nvim/pos.h" @@ -414,6 +415,7 @@ int bck_word(long count, bool bigword, bool stop) finished: stop = false; } + adjust_skipcol(); return OK; } @@ -518,6 +520,7 @@ int bckend_word(long count, bool bigword, bool eol) } } } + adjust_skipcol(); return OK; } diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 35f46e512d..00a3922a5b 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -2667,7 +2667,7 @@ void ex_undolist(exarg_T *eap) undo_fmt_time(IObuff + strlen(IObuff), IOSIZE - strlen(IObuff), uhp->uh_time); if (uhp->uh_save_nr > 0) { while (strlen(IObuff) < 33) { - STRCAT(IObuff, " "); + xstrlcat(IObuff, " ", IOSIZE); } vim_snprintf_add(IObuff, IOSIZE, " %3ld", uhp->uh_save_nr); } |