darktable-org / darktable-org/darktable
RFC: OpenCode run on every PR
Nobody has claimed this yet.
- 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_modulecallsget_params(allocates/copies)dt_lib_get_active_preset_namecompiles a SQL query + iterates rows +memcmps blobs- This runs even for modules with
has_preset_label()returningFALSE(the widget exists, somodule->preset_labelis 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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