Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/ubuntu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ jobs:
gcov-exec: llvm-cov-15 gcov
codecov: ubuntu

- name: Build - Ubuntu 26 Clang
runs-on: ubuntu-26.04
compiler: clang
cxx-compiler: clang++
cmake-args: -G Ninja -D PROXYRES_CODE_COVERAGE=ON
packages: llvm-21 libjavascriptcoregtk-6.0-dev gsettings-desktop-schemas
gcov-exec: llvm-cov-21 gcov
codecov: ubuntu

- name: Build - Ubuntu Clang (curl)
runs-on: ubuntu-latest
compiler: clang
Expand All @@ -50,6 +59,15 @@ jobs:
gcov-exec: llvm-cov-15 gcov
codecov: ubuntu_curl

- name: Build - Ubuntu 26 Clang (curl)
runs-on: ubuntu-26.04
compiler: clang
cxx-compiler: clang++
cmake-args: -G Ninja -D PROXYRES_CODE_COVERAGE=ON -D PROXYRES_CURL=ON
packages: llvm-21 libjavascriptcoregtk-6.0-dev gsettings-desktop-schemas
gcov-exec: llvm-cov-21 gcov
codecov: ubuntu_curl

- name: Build - Ubuntu Clang (duktape)
runs-on: ubuntu-latest
compiler: clang
Expand All @@ -59,6 +77,15 @@ jobs:
gcov-exec: llvm-cov-15 gcov
codecov: ubuntu_duktape

- name: Build - Ubuntu 26 Clang (duktape)
runs-on: ubuntu-26.04
compiler: clang
cxx-compiler: clang++
cmake-args: -G Ninja -D PROXYRES_CODE_COVERAGE=ON -D PROXYRES_DUKTAPE=ON
packages: llvm-21 libglib2.0-dev gsettings-desktop-schemas
gcov-exec: llvm-cov-21 gcov
codecov: ubuntu_duktape

steps:
- name: Install dependencies
run: |
Expand Down
29 changes: 25 additions & 4 deletions config_gnome3.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,27 @@ typedef struct g_proxy_config_gnome3_s {
// Glib module handle
void *glib_module;
// Glib memory functions
#if G_GNUC_CHECK_VERSION(4, 1) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_78 && defined(G_HAVE_FREE_SIZED)
void (*g_free_sized)(gpointer mem, size_t size);
#endif
void (*g_free)(gpointer mem);
void (*g_strfreev)(gchar **str_array);
} g_proxy_config_gnome3_s;

g_proxy_config_gnome3_s g_proxy_config_gnome3;

#ifdef g_free
# undef g_free
# if G_GNUC_CHECK_VERSION(4, 1) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_78 && defined(G_HAVE_FREE_SIZED)
# define g_free(mem) \
(__builtin_object_size((mem), 0) != ((size_t)-1)) \
? (g_proxy_config_gnome3.g_free_sized)(mem, __builtin_object_size((mem), 0)) \
: (g_proxy_config_gnome3.g_free)(mem)
Comment thread
nmoinvaz marked this conversation as resolved.
# else
# define g_free(mem) (g_proxy_config_gnome3.g_free)(mem)
# endif
#endif
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Comment on lines +37 to +48

@coderabbitai coderabbitai Bot Jul 13, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== config_gnome3.c relevant lines ==\n'
nl -ba config_gnome3.c | sed -n '1,220p'

printf '\n== search for gfree / g_free references ==\n'
rg -n '\bgfree\b|\bg_free\b|G_HAVE_FREE_SIZED|GLIB_VERSION_MAX_ALLOWED' config_gnome3.c

Repository: snxd/proxyres

Length of output: 229


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== surrounding context for call sites ==\n'
nl -ba config_gnome3.c | sed -n '48,170p'

Repository: snxd/proxyres

Length of output: 233


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# If the file exists elsewhere, locate it and inspect exact sections.
file="$(git ls-files '*config_gnome3.c' | head -n 1)"
printf 'file=%s\n' "$file"
nl -ba "$file" | sed -n '1,220p'

Repository: snxd/proxyres

Length of output: 212


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== config_gnome3.c relevant lines ==\n'
sed -n '1,220p' config_gnome3.c

printf '\n== search for gfree / g_free references ==\n'
grep -nE '\bgfree\b|\bg_free\b|G_HAVE_FREE_SIZED|GLIB_VERSION_MAX_ALLOWED' config_gnome3.c

Repository: snxd/proxyres

Length of output: 9392


Fix the g_free fallback macro The #else branch currently defines gfree, so g_free(...) falls back to the GLib symbol instead of g_proxy_config_gnome3.g_free on builds without sized-free support. The outer #ifdef g_free also skips the wrapper entirely unless GLib exposes g_free as a macro.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@config_gnome3.c` around lines 37 - 48, The fallback branch must define
g_free, not gfree, and the wrapper must be installed regardless of whether GLib
already defines g_free as a macro. Update the preprocessor structure around the
g_free wrapper so any existing definition is removed when present, then define
g_free to call g_proxy_config_gnome3.g_free in builds without sized-free
support.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what do you propose?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nmoinvaz, here's the concrete fix — the wrapper should always be installed (not just when glib already defines g_free as a macro), and the fallback branch should define g_free, not gfree:

`#ifdef` g_free
#  undef g_free
`#endif`
`#if` G_GNUC_CHECK_VERSION(4, 1) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_78 && defined(G_HAVE_FREE_SIZED)
#  define g_free(mem)                                                                  \
    (__builtin_object_size((mem), 0) != ((size_t)-1))                                  \
        ? (g_proxy_config_gnome3.g_free_sized)(mem, __builtin_object_size((mem), 0))   \
        : (g_proxy_config_gnome3.g_free)(mem)
`#else`
#  define g_free(mem) (g_proxy_config_gnome3.g_free)(mem)
`#endif`

Two changes from the current code:

  1. Removed the outer #ifdef g_free gate around the whole block. In most glib builds, g_free is declared as a plain function (not a macro), so the current #ifdef g_free check is false and the wrapper never activates — meaning sized-free is silently skipped even on systems that support it, and the wrapper is generally moot. #undef is a safe no-op if g_free isn't currently a macro, so it's fine to always attempt it before defining our own macro.
  2. Fixed the typo in the fallback branch: #define gfree(mem) ...#define g_free(mem) ..., since the misspelled name meant that on builds without sized-free support, calls to g_free(...) in this file wouldn't route through g_proxy_config_gnome3.g_free at all (they'd resolve to the real GLib g_free, which wasn't loaded via dlsym/is separately linked, potentially bypassing the dlopen'd module design).

Let me know if you'd like me to open a PR-scoped follow-up or if you want to apply this directly.

static bool proxy_config_gnome3_is_mode(const char *mode) {
bool equal = false;

Expand All @@ -41,7 +56,7 @@ static bool proxy_config_gnome3_is_mode(const char *mode) {
char *system_mode = g_proxy_config_gnome3.g_settings_get_string(settings, "mode");
if (system_mode) {
equal = strcmp(system_mode, mode) == 0;
g_proxy_config_gnome3.g_free(system_mode);
g_free(system_mode);
}
g_proxy_config_gnome3.g_object_unref(settings);
return equal;
Expand All @@ -63,7 +78,7 @@ char *proxy_config_gnome3_get_auto_config_url(void) {
if (url) {
if (*url)
auto_config_url = strdup(url);
g_proxy_config_gnome3.g_free(url);
g_free(url);
}
g_proxy_config_gnome3.g_object_unref(settings);
return auto_config_url;
Expand Down Expand Up @@ -108,7 +123,7 @@ char *proxy_config_gnome3_get_proxy(const char *scheme) {
snprintf(proxy, max_proxy, "%s:%" PRIu32 "", host, port);
}

g_proxy_config_gnome3.g_free(host);
g_free(host);
}
g_proxy_config_gnome3.g_object_unref(settings);
return proxy;
Expand Down Expand Up @@ -162,9 +177,15 @@ bool proxy_config_gnome3_global_init(void) {
goto gnome3_init_error;

// Glib functions
g_proxy_config_gnome3.g_free = (void (*)(gpointer))dlsym(g_proxy_config_gnome3.glib_module, "g_free");
(g_proxy_config_gnome3.g_free) = (void (*)(gpointer))dlsym(g_proxy_config_gnome3.glib_module, "g_free");
if (!g_proxy_config_gnome3.g_free)
goto gnome3_init_error;
#if G_GNUC_CHECK_VERSION(4, 1) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_78 && defined(G_HAVE_FREE_SIZED)
g_proxy_config_gnome3.g_free_sized =
(void (*)(gpointer, size_t))dlsym(g_proxy_config_gnome3.glib_module, "g_free_sized");
if (!g_proxy_config_gnome3.g_free_sized)
goto gnome3_init_error;
#endif
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment thread
nmoinvaz marked this conversation as resolved.
g_proxy_config_gnome3.g_strfreev = (void (*)(gchar **))dlsym(g_proxy_config_gnome3.glib_module, "g_strfreev");
if (!g_proxy_config_gnome3.g_strfreev)
goto gnome3_init_error;
Expand Down
Loading