From cd87d88a930a0b58cfca38678d2e757491c17b26 Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Thu, 7 Mar 2024 21:56:36 +0100 Subject: Fix asan errors It found some really nasty ones :) --- Makefile | 9 ++++++++- src/dged/buffer.c | 3 +++ src/dged/settings.c | 13 ++++++++++--- src/dged/text.c | 7 ++++++- src/dged/vec.h | 2 ++ src/main/completion.c | 2 +- test/buffer.c | 4 ++++ test/minibuffer.c | 1 + 8 files changed, 35 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index d469509..43b2be9 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,13 @@ datadir = $(prefix)/share/dged CFLAGS += -Werror -g -O2 -std=c99 -I $(.CURDIR)/src -I $(.CURDIR)/src/main -DDATADIR="$(datadir)" +ASAN ?= false + +.if $(ASAN:tl) == true +CFLAGS += -fsanitize=address -fno-omit-frame-pointer +LDFLAGS += -fsanitize=address +.endif + .if $(SYNTAX_ENABLE:tl) == true HEADERS += src/dged/syntax.h SOURCES += src/dged/syntax.c @@ -73,7 +80,7 @@ FILES = $(DEPS) $(MAIN_OBJS) $(OBJS) dged libdged.a $(TEST_OBJS) $(PLATFORM_OBJS grammars: if [ -n "$$TREESITTER_GRAMMARS" ]; then \ IFS=":"; for p in "$$TREESITTER_GRAMMARS"; do \ - cp -rL "$$p"/ grammars; \ + cp -rL --no-preserve=mode "$$p"/ grammars; \ done \ else \ @echo "TODO: download and build default set of grammars"; \ diff --git a/src/dged/buffer.c b/src/dged/buffer.c index d25297f..ab86dc6 100644 --- a/src/dged/buffer.c +++ b/src/dged/buffer.c @@ -837,6 +837,9 @@ void buffer_find(struct buffer *buffer, const char *pattern, *matches = VEC_ENTRIES(&data.matches); *nmatches = VEC_SIZE(&data.matches); + + VEC_DISOWN_ENTRIES(&data.matches); + VEC_DESTROY(&data.matches); } struct location buffer_copy(struct buffer *buffer, struct region region) { diff --git a/src/dged/settings.c b/src/dged/settings.c index df3af1c..3dc92ef 100644 --- a/src/dged/settings.c +++ b/src/dged/settings.c @@ -63,7 +63,6 @@ struct setting *settings_get(const char *path) { void settings_get_prefix(const char *prefix, struct setting **settings_out[], uint32_t *nsettings_out) { - uint32_t capacity = 16; VEC(struct setting *) res; VEC_INIT(&res, 16); HASHMAP_FOR_EACH(&g_settings.settings, struct setting_entry * entry) { @@ -75,6 +74,9 @@ void settings_get_prefix(const char *prefix, struct setting **settings_out[], *nsettings_out = VEC_SIZE(&res); *settings_out = VEC_ENTRIES(&res); + + VEC_DISOWN_ENTRIES(&res); + VEC_DESTROY(&res); } void settings_set(const char *path, struct setting_value value) { @@ -194,13 +196,18 @@ static int32_t parse_toml(struct parser *state, char **errmsgs[]) { free(curkey); } + uint32_t ret = 0; if (!VEC_EMPTY(&errs)) { *errmsgs = VEC_ENTRIES(&errs); + ret = VEC_SIZE(&errs); + + VEC_DISOWN_ENTRIES(&errs); + VEC_DESTROY(&errs); } else { *errmsgs = NULL; VEC_DESTROY(&errs); } - return VEC_SIZE(&errs); + return ret; } struct str_cursor { @@ -272,7 +279,7 @@ static size_t get_bytes_from_file(size_t nbytes, uint8_t *buf, void *userdata) { memcpy(buf, r->buffer, to_read); r->buflen -= to_read; - memcpy(r->buffer, r->buffer + to_read, r->buflen); + memmove(r->buffer, r->buffer + to_read, r->buflen); return to_read; } diff --git a/src/dged/text.c b/src/dged/text.c index 0a92933..82c49bc 100644 --- a/src/dged/text.c +++ b/src/dged/text.c @@ -77,9 +77,14 @@ void text_clear(struct text *text) { // given `char_idx` as a character index, return the byte index uint32_t charidx_to_byteidx(struct line *line, uint32_t char_idx) { + if (line->nchars == 0) { + return 0; + } + if (char_idx > line->nchars) { - return line->nbytes; + return line->nbytes - 1; } + return utf8_nbytes(line->data, line->nbytes, char_idx); } diff --git a/src/dged/vec.h b/src/dged/vec.h index 8b17fa5..929c8d5 100644 --- a/src/dged/vec.h +++ b/src/dged/vec.h @@ -17,6 +17,8 @@ (vec)->capacity = initial_capacity; \ (vec)->nentries = 0; +#define VEC_DISOWN_ENTRIES(vec) (vec)->entries = NULL; + #define VEC_DESTROY(vec) \ free((vec)->temp); \ free((vec)->entries); \ diff --git a/src/main/completion.c b/src/main/completion.c index acf7a78..4735c87 100644 --- a/src/main/completion.c +++ b/src/main/completion.c @@ -456,7 +456,7 @@ static uint32_t complete_path(struct completion_context ctx, void *userdata) { // check the input path here since // to_abspath removes trailing slashes - if (path[inlen - 1] != '/') { + if (inlen == 0 || path[inlen - 1] != '/') { dir = dirname(p1); file = basename(p2); } diff --git a/test/buffer.c b/test/buffer.c index f4aefc5..a4b318e 100644 --- a/test/buffer.c +++ b/test/buffer.c @@ -15,6 +15,8 @@ void test_add() { ASSERT(loc.line == 1 && loc.col == strlen(txt), "Expected buffer to have one line with characters"); + + buffer_destroy(&b); } void test_word_at() { @@ -43,6 +45,8 @@ void test_word_at() { ASSERT(region_has_size(word3), "expected 0,100 to be in the last word"); ASSERT(word3.begin.col == 15 && word3.end.col == 22, "Expected word to span cols 15..22"); + + buffer_destroy(&b); } void run_buffer_tests() { diff --git a/test/minibuffer.c b/test/minibuffer.c index 96fecca..5243b6c 100644 --- a/test/minibuffer.c +++ b/test/minibuffer.c @@ -34,6 +34,7 @@ void init() { void destroy() { if (b.name != NULL) { buffer_destroy(&b); + buffers_destroy(&bufs); settings_destroy(); timers_destroy(); windows_destroy(); -- cgit v1.2.3