darktable-org / darktable-org/darktable

RFC: OpenCode run on every PR

Open
#20,960 14 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

no-issue-activity
Dominant language
C
Stars
13.1k
Forks
1.4k
Avg merge
22h 14m
Merged PRs (30d)
198

Description

On a recent PR just merged I decided to see what OpenCode could say. In less than 2 minutes I got this report from a large prompt asking to check many part of the code (security, race conditions...).

1. free() vs g_free() allocator mismatch in _free_module_info (MEDIUM)

src/libs/lib.c:466: Changed from g_free(minfo->params) to free(minfo->params). The params pointer comes from module->get_params(), which may return memory allocated with g_malloc (varies by module). On platforms where glib uses a different heap (e.g., Windows debug builds), this is UB. The old code used g_free, which is safe for both malloc and g_malloc on most glib platforms.

Fix: Revert to g_free(minfo->params).

2. dt_lib_gui_update fires expensive SQL query on every draw (MEDIUM)

src/libs/lib.c:921-928: The preset label update code runs outside the gui_uptodate guard, so it executes on every single draw event for every expandable module. For each draw:

  • _get_module_info_for_module calls get_params (allocates/copies)
  • dt_lib_get_active_preset_name compiles a SQL query + iterates rows + memcmps blobs
  • This runs even for modules with has_preset_label() returning FALSE (the widget exists, so module->preset_label is non-NULL)

With N expandable modules visible, that's N SQL queries per draw frame.

Fix: Guard with module->has_preset_label(module) check before the expensive block, and/or cache the active preset name and only re-query when params actually change.

3. No NULL guard in _lib_gui_reset_callback and dt_lib_reset_preset_label (LOW)

src/libs/lib.c:971: Calls gtk_label_set_text(GTK_LABEL(module->preset_label), "") without NULL-checking module->preset_label.

src/libs/lib.c:1681: Same in dt_lib_reset_preset_label — no NULL check on mod or mod->preset_label.

_lib_gui_reset_callback is called from _action_process (keyboard shortcut) for any module with gui_reset, but preset_label is only created in dt_lib_gui_get_expander for expandable modules. Currently no module has gui_reset without an expander, but this is a latent crash.

Fix: Add if(!module->preset_label) return; at the top of _lib_gui_reset_callback. Add if(!mod || !mod->preset_label) return; in dt_lib_reset_preset_label.

4. Redundant/non-standard #include <glib-2.0/glib.h> (LOW)

src/libs/lib.c:33: Uses <glib-2.0/glib.h> which relies on /usr/include being in the default compiler search path. The conventional path is <glib.h> (resolved via pkg-config -isystem paths). Additionally, glib.h is already transitively included through lib.h -> <gtk/gtk.h>, through lib_api.h, and through module_api.h. This include is entirely redundant.

Fix: Remove the line entirely (glib.h is already available via transitive includes). If kept, use #include <glib.h>.

5. Empty #ifdef GDK_WINDOWING_QUARTZ block (LOW)

src/libs/lib.c:35-36: After removing #include "osx/osx.h", the conditional block is empty. Dead code.

Fix: Remove the empty #ifdef/#endif.

6. Widget created unconditionally for all expandable modules (LOW)

src/libs/lib.c:1344-1349: preset_label widget is created in dt_lib_gui_get_expander for all expandable modules, even those where has_preset_label() defaults to FALSE. The widget exists but is never updated (a dead GtkLabel in the layout). Minor memory/waste but also forces the per-frame SQL query described in issue #2 (since module->preset_label is non-NULL).

Fix: Guard widget creation with if(module->has_preset_label(module)).

Originally posted by @TurboGit in https://github.com/darktable-org/darktable/issues/18468#issuecomment-4408292319

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/libs/lib.c and read _free_module_info, dt_lib_gui_update, _lib_gui_reset_callback, dt_lib_reset_preset_label, and dt_lib_gui_get_expander at the listed locations. Check each reported allocator, guard, include, conditional, query, and widget-creation issue; done means the six described problems are addressed without the reported crash, repeated query, or dead widget behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
desktop, performance
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.