diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fbe80c187..8ca9b6cf7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,6 +21,7 @@ concurrency: env: CFLAGS: -g -O2 -Werror=pointer-arith -Werror=implicit-function-declaration CONFIGURE_FLAGS: --disable-silent-rules + CPPCHECKFLAGS: --check-level=exhaustive CCACHE_DIR: ${{ github.workspace }}/.ccache CCACHE_COMPRESS: true CCACHE_MAXSIZE: 1G @@ -190,7 +191,7 @@ jobs: - name: Run distcheck run: | cd _build - make -j ${{ env.JOBS }} distcheck DISTCHECK_CONFIGURE_FLAGS="${{ env.CONFIGURE_FLAGS }}"; + make -j ${{ env.JOBS }} distcheck DISTCHECK_CONFIGURE_FLAGS="${{ env.CONFIGURE_FLAGS }} --disable-cppcheck"; - name: ccache statistics if: ${{ env.DEBUG == '1' }} diff --git a/addons/src/ao_tasks.c b/addons/src/ao_tasks.c index 0cee91ec9..9f5729976 100644 --- a/addons/src/ao_tasks.c +++ b/addons/src/ao_tasks.c @@ -636,18 +636,21 @@ static void free_update_tasks_for_doc_arguments(gpointer data) static void update_tasks_for_doc(AoTasks *t, GeanyDocument *doc, gboolean clear) { - AoTasksUpdateTasksForDocArguments *arguments = g_slice_alloc(sizeof *arguments); - arguments->t = t; - arguments->doc = doc; - arguments->clear = clear; + AoTasksUpdateTasksForDocArguments *arguments; if (!DOC_VALID(doc)) return; + arguments = g_slice_alloc(sizeof *arguments); + arguments->t = t; + arguments->doc = doc; + arguments->clear = clear; + /* Check for task tokens in an idle callback to wait until Geany applied Scintilla highlighting * styles as we need them to be set before checking for tasks. */ g_idle_add_full(G_PRIORITY_LOW, update_tasks_for_doc_idle_cb, arguments, free_update_tasks_for_doc_arguments); + /* cppcheck-suppress memleak symbolName=arguments */ } diff --git a/build/cppcheck-geany-plugins.cfg b/build/cppcheck-geany-plugins.cfg index 88fbe8ec8..0647ab26c 100644 --- a/build/cppcheck-geany-plugins.cfg +++ b/build/cppcheck-geany-plugins.cfg @@ -1,11 +1,7 @@ - - - - diff --git a/build/cppcheck.mk b/build/cppcheck.mk index e1a5e01e0..8874a1ad2 100644 --- a/build/cppcheck.mk +++ b/build/cppcheck.mk @@ -3,9 +3,15 @@ if HAVE_CPPCHECK check-cppcheck: $(srcdir) $(CPPCHECK) \ + --inline-suppr \ -q --template=gcc --error-exitcode=2 \ + --library=gtk \ --library=$(top_srcdir)/build/cppcheck-geany-plugins.cfg \ -I$(GEANY_INCLUDEDIR)/geany \ + -UGEANY_PRIVATE \ + -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \ + $(filter -j%,$(MAKEFLAGS)) \ + $(LOCAL_AM_CFLAGS) \ $(AM_CPPCHECKFLAGS) $(CPPCHECKFLAGS) \ $(srcdir) diff --git a/geanyctags/src/geanyctags.c b/geanyctags/src/geanyctags.c index 96283ded6..6e5ed8428 100644 --- a/geanyctags/src/geanyctags.c +++ b/geanyctags/src/geanyctags.c @@ -162,6 +162,8 @@ static void spawn_cmd(const gchar *cmd, const gchar *dir) msgwin_msg_add(COLOR_BLACK, -1, NULL, "%s", out); } + /* cppcheck-suppress mismatchAllocDealloc symbolName=argv + * argv is built manually, but is a valid GStrv */ g_strfreev(argv); g_free(working_dir); g_free(out); diff --git a/geanygendoc/src/ggd-options.c b/geanygendoc/src/ggd-options.c index 123721feb..e691b7678 100644 --- a/geanygendoc/src/ggd-options.c +++ b/geanygendoc/src/ggd-options.c @@ -202,6 +202,7 @@ ggd_opt_group_add_entry (GgdOptGroup *group, g_array_append_val (group->prefs, entry); + /* cppcheck-suppress memleak symbolName=entry.key */ return &g_array_index (group->prefs, GgdOptEntry, group->prefs->len -1); } diff --git a/geanyprj/src/Makefile.am b/geanyprj/src/Makefile.am index ef9e8df6c..8b921681e 100644 --- a/geanyprj/src/Makefile.am +++ b/geanyprj/src/Makefile.am @@ -23,7 +23,4 @@ unittests_CFLAGS = $(GEANY_CFLAGS) -DUNITTESTS unittests_LDADD = @GEANY_LIBS@ $(INTLLIBS) @CHECK_LIBS@ endif -AM_CPPCHECKFLAGS = --suppress='constStatement:*' -AM_CPPCHECKFLAGS += --suppress='memleak:utils.c:72' - include $(top_srcdir)/build/cppcheck.mk diff --git a/geanyprj/src/utils.c b/geanyprj/src/utils.c index 281e87cc4..f8a3e6d8d 100644 --- a/geanyprj/src/utils.c +++ b/geanyprj/src/utils.c @@ -69,7 +69,10 @@ gchar *normpath(const gchar *filename) return g_strdup("."); v = g_strsplit_set(filename, "/\\", -1); if (!g_strv_length(v)) + { + g_strfreev(v); return g_strdup("."); + } out = g_malloc0(sizeof(gchar *) * (g_strv_length(v) + 2)); pout = out; diff --git a/geniuspaste/src/geniuspaste.c b/geniuspaste/src/geniuspaste.c index 1815905c5..27035bd01 100644 --- a/geniuspaste/src/geniuspaste.c +++ b/geniuspaste/src/geniuspaste.c @@ -381,6 +381,8 @@ static gchar *pastebin_get_language(const Pastebin *pastebin, gchar *lang = g_key_file_get_string(pastebin->config, PASTEBIN_GROUP_LANGUAGES, geany_ft_name, NULL); + /* cppcheck-suppress memleak symbolName=lang + * obvious cppcheck bug */ return lang ? lang : pastebin_get_default(pastebin, "language", ""); } @@ -750,6 +752,9 @@ static void show_msgbox(GtkMessageType type, GtkButtonsType buttons, /* run the dialog */ gtk_dialog_run(GTK_DIALOG(dlg)); gtk_widget_destroy(dlg); + + g_free(markup); + /* cppcheck-suppress memleak symbolName=dlg */ } static void debug_log_message_body(SoupMessage *msg, diff --git a/git-changebar/src/gcb-plugin.c b/git-changebar/src/gcb-plugin.c index b6f8ad5c3..dd054e44e 100644 --- a/git-changebar/src/gcb-plugin.c +++ b/git-changebar/src/gcb-plugin.c @@ -566,6 +566,7 @@ get_cached_blob_contents_async (const gchar *path, } g_async_queue_push (G_queue, job); + /* cppcheck-suppress memleak symbolName=job */ } } diff --git a/markdown/src/conf.c b/markdown/src/conf.c index d54cc9a6b..ad338e15e 100644 --- a/markdown/src/conf.c +++ b/markdown/src/conf.c @@ -233,7 +233,7 @@ markdown_config_get_string_key(MarkdownConfig *conf, const gchar *group, GError *error = NULL; out_str = g_key_file_get_string(conf->priv->kf, group, key, &error); - if (error) { + if (!out_str) { g_debug("Config read failed: %s", error->message); g_error_free(error); error = NULL; out_str = g_strdup(default_value); @@ -451,7 +451,7 @@ markdown_config_save(MarkdownConfig *conf) /*g_debug("Saving: %s\n%s", conf->priv->filename, contents);*/ - if (error) { + if (!contents) { g_warning("Error getting config data as string: %s", error->message); g_error_free(error); error = NULL; return success; diff --git a/scope/src/Makefile.am b/scope/src/Makefile.am index c161b8ef7..b3398bc38 100644 --- a/scope/src/Makefile.am +++ b/scope/src/Makefile.am @@ -60,8 +60,6 @@ scope_la_CFLAGS = $(AM_CFLAGS) $(VTE_CFLAGS) \ -Wno-shadow \ -I$(top_srcdir)/utils/src -AM_CPPCHECKFLAGS = -DGETTEXT_PACKAGE="geany-plugins" - include $(top_srcdir)/build/cppcheck.mk if UNITTESTS diff --git a/scope/src/debug.c b/scope/src/debug.c index 6974078e7..769bba942 100644 --- a/scope/src/debug.c +++ b/scope/src/debug.c @@ -207,6 +207,8 @@ static void create_send_source(void) g_source_set_callback(send_source, (GSourceFunc) send_commands_cb, NULL, send_source_destroy_cb); send_source_id = g_source_attach(send_source, NULL); + /* cppcheck-suppress memleak symbolName=send_source + * the source is attached and managed through its ID */ } #define HAS_SPAWN_LEAVE_STDIN_OPEN 0 @@ -347,6 +349,8 @@ static void gdb_finalize(void) if (send_channel) { g_io_channel_shutdown(send_channel, FALSE, NULL); + /* cppcheck-suppress doubleFree symbolName=send_channel + * erroneously thinks g_io_channel_shutdown() frees the channel */ g_io_channel_unref(send_channel); send_channel = NULL; diff --git a/treebrowser/src/Makefile.am b/treebrowser/src/Makefile.am index d5bd178f1..147275e93 100644 --- a/treebrowser/src/Makefile.am +++ b/treebrowser/src/Makefile.am @@ -10,7 +10,4 @@ treebrowser_la_CFLAGS = $(AM_CFLAGS) $(GIO_CFLAGS) \ treebrowser_la_LIBADD = $(COMMONLIBS) $(GIO_LIBS) \ $(top_builddir)/utils/src/libgeanypluginutils.la -AM_CPPCHECKFLAGS = --suppress='deallocDealloc:$(srcdir)/treebrowser.c' -AM_CPPCHECKFLAGS += --suppress='doubleFree:$(srcdir)/treebrowser.c' - include $(top_srcdir)/build/cppcheck.mk diff --git a/treebrowser/src/treebrowser.c b/treebrowser/src/treebrowser.c index 0fc8e0191..5441cd047 100644 --- a/treebrowser/src/treebrowser.c +++ b/treebrowser/src/treebrowser.c @@ -1121,6 +1121,7 @@ on_menu_create_new_object(GtkMenuItem *menuitem, const gchar *type) } g_free(uri_new); } + /* cppcheck-suppress doubleFree symbolName=uri */ g_free(uri); } @@ -1192,6 +1193,7 @@ on_menu_refresh(GtkMenuItem *menuitem, gpointer *user_data) } } treebrowser_browse(uri, target_iter); + /* cppcheck-suppress doubleFree symbolName=uri */ g_free(uri); } else diff --git a/vimode/src/cmd-runner.c b/vimode/src/cmd-runner.c index 49706a539..e773777ad 100644 --- a/vimode/src/cmd-runner.c +++ b/vimode/src/cmd-runner.c @@ -707,6 +707,8 @@ static gboolean process_cmd(CmdDef *cmds, CmdContext *ctx, gboolean ins_mode) } else if (!consumed && ctx->kpl) { + /* cppcheck-suppress deallocuse symbolName=kpl + * Not sure how cppcheck gets this wrong here, but all seem OK */ g_free(ctx->kpl->data); ctx->kpl = g_slist_delete_link(ctx->kpl, ctx->kpl); } diff --git a/workbench/src/sidebar.c b/workbench/src/sidebar.c index 4e5c8fe47..0b6da7b2f 100644 --- a/workbench/src/sidebar.c +++ b/workbench/src/sidebar.c @@ -213,6 +213,8 @@ static void sidebar_create_branch(gint level, const gchar *abs_base_dir, GSList FILEVIEW_COLUMN_ICON, icon_dir, FILEVIEW_COLUMN_NAME, last_dir_name, FILEVIEW_COLUMN_DATA_ID, DATA_ID_SUB_DIRECTORY, + /* cppcheck-suppress leakNoVarFunctionCall + * type is gpointer, but admittedly I don't see where it's freed? */ FILEVIEW_COLUMN_ASSIGNED_DATA_POINTER, g_strdup(full), -1); @@ -235,6 +237,8 @@ static void sidebar_create_branch(gint level, const gchar *abs_base_dir, GSList FILEVIEW_COLUMN_ICON, icon_dir, FILEVIEW_COLUMN_NAME, last_dir_name, FILEVIEW_COLUMN_DATA_ID, DATA_ID_SUB_DIRECTORY, + /* cppcheck-suppress leakNoVarFunctionCall + * type is gpointer, but admittedly I don't see where it's freed? */ FILEVIEW_COLUMN_ASSIGNED_DATA_POINTER, g_strdup(full), -1); g_free(full); @@ -440,6 +444,8 @@ static void sidebar_add_file (WB_PROJECT *prj, WB_PROJECT_DIR *root, const gchar FILEVIEW_COLUMN_ICON, icon, FILEVIEW_COLUMN_NAME, name, FILEVIEW_COLUMN_DATA_ID, dataid, + /* cppcheck-suppress leakNoVarFunctionCall + * type is gpointer, but admittedly I don't see where it's freed? */ FILEVIEW_COLUMN_ASSIGNED_DATA_POINTER, g_strdup(filepath), -1); diff --git a/workbench/src/wb_project.c b/workbench/src/wb_project.c index 626f8e149..041c3a5f8 100644 --- a/workbench/src/wb_project.c +++ b/workbench/src/wb_project.c @@ -691,6 +691,7 @@ static guint wb_project_dir_rescan_int(WB_PROJECT *prj, WB_PROJECT_DIR *root) if (path) { + /* cppcheck-suppress leakNoVarFunctionCall -- key is freed automatically */ g_hash_table_add(root->file_table, g_strdup(path)); filenum++; } @@ -757,6 +758,7 @@ static void wb_project_dir_add_file_int(WB_PROJECT *prj, WB_PROJECT_DIR *root, c } /* Update file table and counters. */ + /* cppcheck-suppress leakNoVarFunctionCall -- key is freed automatically */ g_hash_table_add(root->file_table, g_strdup(filepath)); if (g_file_test(filepath, G_FILE_TEST_IS_DIR)) { @@ -818,6 +820,7 @@ static void wb_project_dir_update_tags(WB_PROJECT_DIR *root) gchar *locale_path = utils_get_locale_from_utf8(utf8_path); g_ptr_array_add(files, g_strdup(key)); + /* cppcheck-suppress leakNoVarFunctionCall -- key is freed automatically */ g_hash_table_add(root->file_table, g_strdup(utf8_path)); g_free(locale_path); } @@ -960,6 +963,7 @@ static void wb_project_dir_regenerate_tags(WB_PROJECT_DIR *root, G_GNUC_UNUSED g } /* Add all files to the file-table (files and dirs)! */ + /* cppcheck-suppress leakNoVarFunctionCall -- key is freed automatically */ g_hash_table_add(file_table, g_strdup(key)); } g_hash_table_destroy(root->file_table); diff --git a/workbench/src/workbench.c b/workbench/src/workbench.c index 30c45d3b7..9dbbc8201 100644 --- a/workbench/src/workbench.c +++ b/workbench/src/workbench.c @@ -833,6 +833,8 @@ gboolean workbench_load(WORKBENCH *wb, const gchar *filename, GError **error) return FALSE; } + g_free (contents); + if (g_key_file_has_key (kf, "General", "filetype", NULL) && g_key_file_has_key (kf, "General", "version", NULL)) { @@ -854,6 +856,7 @@ gboolean workbench_load(WORKBENCH *wb, const gchar *filename, GError **error) g_set_error (error, 0, 0, _("File %s is not a valid workbench file!"), filename); + g_key_file_free (kf); return FALSE; } workbench_set_filename(wb, filename); @@ -964,7 +967,6 @@ gboolean workbench_load(WORKBENCH *wb, const gchar *filename, GError **error) } g_key_file_free(kf); - g_free (contents); success = TRUE; } else if (error != NULL)