From 4b5c253b8961660b9ba1f245086322ecce358977 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Feb 2026 09:28:28 +0100 Subject: [PATCH 1/5] build: Add -Wpointer-arith flag Even though we are using with GNU extensions I will add this flag since I prefer the explicit writing style that we have to use wich this flag enabled. --- meson.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 04ab74d1..3f718192 100644 --- a/meson.build +++ b/meson.build @@ -67,7 +67,8 @@ if is_debug '-Wextra', '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', - '-Og' + '-Og', + '-Wpointer-arith' ], language: 'c') if cc.get_id() == 'gcc' add_project_arguments('-fanalyzer', language: 'c') From c24cdcd67186f136914cdc69fa05accd3faf8a02 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Feb 2026 09:44:27 +0100 Subject: [PATCH 2/5] fix: Fix -Wanalyzer-deref-before-check warning in cmd_ac_complete Adding an explicit NULL check for 'input' at the start of cmd_ac_complete to prevent a potential crash and resolve a GCC static analyzer warning. Quirk Explanation: The analyzer found a "deref-before-check" warning for: `if ((strncmp(input, "/", 1) == 0) && (!strchr(input, ' ')))` The analyzer interpreted 'strchr(input, ' ')' as a point where the validity of 'input' is being questioned (a "check"), even though it is actually checking the return value. This is due to GCC's internal model of certain standard string functions having a 'nonnull' attribute or being categorized as pointer "interrogations" in its state machine. Because 'strncmp' dereferences 'input' earlier in the same line, the analyzer saw a logical contradiction: "You treat it as safe in strncmp, but then you call a function (strchr) that 'requires/checks' it to be safe, implying you weren't sure." --- src/command/cmd_ac.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index a632ceae..19785399 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -1545,6 +1545,10 @@ cmd_ac_remove_form_fields(DataForm* form) char* cmd_ac_complete(ProfWin* window, const char* const input, gboolean previous) { + if (!input) { + return NULL; + } + char* found = NULL; // autocomplete command if ((strncmp(input, "/", 1) == 0) && (!strchr(input, ' '))) { From 434a887834ba5eef22b1b45b2cc3092496332677 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Feb 2026 09:49:55 +0100 Subject: [PATCH 3/5] Fix -Wanalyzer-deref-before-check warning in get_message_from_editor Let's add an explicit check. --- src/tools/editor.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/tools/editor.c b/src/tools/editor.c index 3c5ee823..70bc13f3 100644 --- a/src/tools/editor.c +++ b/src/tools/editor.c @@ -86,12 +86,18 @@ get_message_from_editor(gchar* message, gchar** returned_message) auto_gchar gchar* editor_with_filename = g_strdup_printf("%s %s", editor, filename); auto_gcharv gchar** editor_argv = g_strsplit(editor_with_filename, " ", 0); + if (!editor_argv || !editor_argv[0]) { + log_error("[Editor] Failed to parse editor command: %s", editor); + return TRUE; + } + // Fork / exec pid_t pid = fork(); if (pid == 0) { - int x = execvp(editor_argv[0], editor_argv); - if (x == -1) { - log_error("[Editor] Failed to exec %s", editor); + if (editor_argv && editor_argv[0]) { + int x = execvp(editor_argv[0], editor_argv); + if (x == -1) + log_error("[Editor] Failed to exec %s", editor); } _exit(EXIT_FAILURE); } else { From ab4adf19d0327008a7a302a7e0df40ab86afcf5e Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Feb 2026 10:02:26 +0100 Subject: [PATCH 4/5] refactor: Refactor form_set_value to use glib list management Simplify how field values are updated and ensure memory is correctly managed. The previous implementation relied on manual manipulation of the GSList internal `data` member and only handled cases where a field had zero or one existing value. The function now correctly handles fields that may already contain multiple values by using 'g_slist_free_full' to clear the entire list and its contents before setting the new value. --- src/xmpp/form.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/xmpp/form.c b/src/xmpp/form.c index 8f9e0bc9..1b8f84f4 100644 --- a/src/xmpp/form.c +++ b/src/xmpp/form.c @@ -477,16 +477,13 @@ form_set_value(DataForm* form, const char* const tag, char* value) while (curr) { FormField* field = curr->data; if (g_strcmp0(field->var, var) == 0) { - if (g_slist_length(field->values) == 0) { - field->values = g_slist_append(field->values, strdup(value)); - form->modified = TRUE; - return; - } else if (g_slist_length(field->values) == 1) { - free(field->values->data); - field->values->data = strdup(value); - form->modified = TRUE; - return; + if (field->values) { + g_slist_free_full(field->values, free); + field->values = NULL; } + field->values = g_slist_append(NULL, strdup(value)); + form->modified = TRUE; + return; } curr = g_slist_next(curr); } From 09c930749302377a4d41e2e9c3d45bf4c6a81720 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Feb 2026 10:06:06 +0100 Subject: [PATCH 5/5] ci: build with ASan and UBSan Should help us find the following bugs early. ASan: * Out-of-bounds accesses * Use-after-free * Memory leaks * Double free / Invalid free UBSan: * Undefined Behavior * Signed integer overflow * Null pointer dereference * Pointer misalignment * Division by zero * Bit-shifting out of bounds This needs works during runtime. But let's add it here so that at least basic --version run is test and as a reminder for developer to add it. I will also adjust documentation later on. --- ci-meson-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-meson-build.sh b/ci-meson-build.sh index 0e9ac495..e6333728 100755 --- a/ci-meson-build.sh +++ b/ci-meson-build.sh @@ -39,7 +39,7 @@ tests=( if [[ "$(uname | tr '[:upper:]' '[:lower:]')" == linux* ]]; then echo "--> Running Valgrind check with full features" - meson setup build_valgrind ${tests[0]} -Dtests=true + meson setup build_valgrind ${tests[0]} -Dtests=true -Db_sanitize=address,undefined meson compile -C build_valgrind meson test -C build_valgrind --print-errorlogs --wrap=valgrind || echo "Valgrind issues detected"