From b7693e75ec5715fe549c9a2307e839524d8f9d9a Mon Sep 17 00:00:00 2001 From: deepend Date: Tue, 24 Feb 2026 19:36:36 -0700 Subject: [PATCH 1/4] Updated Linux URL launching in fe_open_url_inner to capture gtk_show_uri errors instead of discarding them, so failures are no longer silent. Added an xdg-open fallback path when gtk_show_uri fails, which improves behavior in AppImage/sandbox-like environments where GTK/GIO handler resolution can fail. Added warning logs for both the primary gtk_show_uri failure and fallback failure to make future debugging much easier. --- src/fe-gtk/fe-gtk.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c index 7967bde6..a657bdb4 100644 --- a/src/fe-gtk/fe-gtk.c +++ b/src/fe-gtk/fe-gtk.c @@ -1680,9 +1680,29 @@ fe_open_url_inner (const char *url) #elif defined(__APPLE__) osx_show_uri (url); #else + GError *error = NULL; char *escaped_url = maybe_escape_uri (url); + gchar *xdg_open_argv[] = {(gchar *) "xdg-open", escaped_url, NULL}; g_debug ("Opening URL \"%s\" (%s)", escaped_url, url); - gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, NULL); + if (gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, &error)) + { + g_free (escaped_url); + return; + } + + g_warning ("gtk_show_uri failed for '%s': %s", escaped_url, error ? error->message : "unknown error"); + g_clear_error (&error); + + /* AppImage and sandboxed environments can fail to resolve URI handlers + * through GTK/GIO. Fall back to xdg-open when available. */ + if (!g_spawn_async (NULL, xdg_open_argv, NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, &error)) + { + g_warning ("xdg-open fallback failed for '%s': %s", escaped_url, error ? error->message : "unknown error"); + g_clear_error (&error); + } + g_free (escaped_url); #endif } From 4284cb76c19ddd8b84f00a8116f711d405ee3572 Mon Sep 17 00:00:00 2001 From: deepend Date: Tue, 24 Feb 2026 20:13:48 -0700 Subject: [PATCH 2/4] Updated Linux URL opening fallback in fe_open_url_inner to launch xdg-open with a sanitized environment instead of inheriting AppImage runtime linker vars. Specifically, LD_LIBRARY_PATH and LD_PRELOAD are removed before spawning, which prevents host /bin/sh and related tools from loading incompatible bundled libraries (the root cause of the rl_trim_arg_from_keyseq symbol error). Kept the existing behavior of trying gtk_show_uri first and only using xdg-open as fallback; this change only hardens the fallback path and preserves existing flow/logging. --- src/fe-gtk/fe-gtk.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c index a657bdb4..bbd07d16 100644 --- a/src/fe-gtk/fe-gtk.c +++ b/src/fe-gtk/fe-gtk.c @@ -1683,6 +1683,7 @@ fe_open_url_inner (const char *url) GError *error = NULL; char *escaped_url = maybe_escape_uri (url); gchar *xdg_open_argv[] = {(gchar *) "xdg-open", escaped_url, NULL}; + gchar **spawn_env = NULL; g_debug ("Opening URL \"%s\" (%s)", escaped_url, url); if (gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, &error)) { @@ -1693,9 +1694,22 @@ fe_open_url_inner (const char *url) g_warning ("gtk_show_uri failed for '%s': %s", escaped_url, error ? error->message : "unknown error"); g_clear_error (&error); + /* AppImage runtime variables can point host binaries like /bin/sh at + * bundled libraries, which may not be ABI-compatible with system tools. */ + spawn_env = g_get_environ (); + { + gchar **tmp_env = spawn_env; + spawn_env = g_environ_unsetenv (tmp_env, "LD_LIBRARY_PATH"); + g_strfreev (tmp_env); + + tmp_env = spawn_env; + spawn_env = g_environ_unsetenv (tmp_env, "LD_PRELOAD"); + g_strfreev (tmp_env); + } + /* AppImage and sandboxed environments can fail to resolve URI handlers * through GTK/GIO. Fall back to xdg-open when available. */ - if (!g_spawn_async (NULL, xdg_open_argv, NULL, + if (!g_spawn_async (NULL, xdg_open_argv, spawn_env, G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, NULL, &error)) { @@ -1703,6 +1717,7 @@ fe_open_url_inner (const char *url) g_clear_error (&error); } + g_strfreev (spawn_env); g_free (escaped_url); #endif } From 3ed66f994558ba72561aa155787a677a87bacec6 Mon Sep 17 00:00:00 2001 From: deepend Date: Tue, 24 Feb 2026 20:22:54 -0700 Subject: [PATCH 3/4] Updated Linux URL-opening logic in fe_open_url_inner to sanitize runtime linker env vars (LD_LIBRARY_PATH, LD_PRELOAD) before launching external URL handlers, which is aimed at preventing /bin/sh symbol lookup failures in AppImage-like environments. Changed the flow to prefer xdg-open first (with sanitized env) and only then fall back to gtk_show_uri, instead of trying GTK first under a potentially broken runtime environment. Added explicit final warning when both mechanisms fail, and ensured temporary allocations (including xdg_open_path) are released cleanly. --- src/fe-gtk/fe-gtk.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c index bbd07d16..568d0d1b 100644 --- a/src/fe-gtk/fe-gtk.c +++ b/src/fe-gtk/fe-gtk.c @@ -1684,15 +1684,8 @@ fe_open_url_inner (const char *url) char *escaped_url = maybe_escape_uri (url); gchar *xdg_open_argv[] = {(gchar *) "xdg-open", escaped_url, NULL}; gchar **spawn_env = NULL; + gboolean opened = FALSE; g_debug ("Opening URL \"%s\" (%s)", escaped_url, url); - if (gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, &error)) - { - g_free (escaped_url); - return; - } - - g_warning ("gtk_show_uri failed for '%s': %s", escaped_url, error ? error->message : "unknown error"); - g_clear_error (&error); /* AppImage runtime variables can point host binaries like /bin/sh at * bundled libraries, which may not be ABI-compatible with system tools. */ @@ -1707,16 +1700,39 @@ fe_open_url_inner (const char *url) g_strfreev (tmp_env); } - /* AppImage and sandboxed environments can fail to resolve URI handlers - * through GTK/GIO. Fall back to xdg-open when available. */ - if (!g_spawn_async (NULL, xdg_open_argv, spawn_env, - G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, - NULL, NULL, NULL, &error)) + /* Prefer xdg-open when available because gtk_show_uri can inherit + * AppImage runtime state and fail before we can control the environment. */ { - g_warning ("xdg-open fallback failed for '%s': %s", escaped_url, error ? error->message : "unknown error"); + gchar *xdg_open_path = g_find_program_in_path ("xdg-open"); + if (xdg_open_path && + g_spawn_async (NULL, xdg_open_argv, spawn_env, + G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, NULL, NULL, &error)) + { + opened = TRUE; + } + else + { + g_clear_error (&error); + } + g_free (xdg_open_path); + } + + if (!opened && gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, &error)) + { + opened = TRUE; + } + else if (!opened) + { + g_warning ("gtk_show_uri failed for '%s': %s", escaped_url, error ? error->message : "unknown error"); g_clear_error (&error); } + if (!opened) + { + g_warning ("Unable to open URL '%s' via xdg-open or gtk_show_uri", escaped_url); + } + g_strfreev (spawn_env); g_free (escaped_url); #endif From 618aecd349b2c269f5cec3e1490ddba191125ea5 Mon Sep 17 00:00:00 2001 From: deepend Date: Tue, 24 Feb 2026 20:29:48 -0700 Subject: [PATCH 4/4] Fixed a crash-prone memory management path in Linux URL launching by only freeing the previous environment vector when g_environ_unsetenv() returns a different pointer. This avoids freeing memory that may still be owned/returned as-is by GLib, which matches your segfault symptoms when opening links from the AppImage build. The fix is in fe_open_url_inner() right where LD_LIBRARY_PATH and LD_PRELOAD are sanitized before spawning xdg-open. --- src/fe-gtk/fe-gtk.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c index 568d0d1b..42f18966 100644 --- a/src/fe-gtk/fe-gtk.c +++ b/src/fe-gtk/fe-gtk.c @@ -1693,11 +1693,13 @@ fe_open_url_inner (const char *url) { gchar **tmp_env = spawn_env; spawn_env = g_environ_unsetenv (tmp_env, "LD_LIBRARY_PATH"); - g_strfreev (tmp_env); + if (spawn_env != tmp_env) + g_strfreev (tmp_env); tmp_env = spawn_env; spawn_env = g_environ_unsetenv (tmp_env, "LD_PRELOAD"); - g_strfreev (tmp_env); + if (spawn_env != tmp_env) + g_strfreev (tmp_env); } /* Prefer xdg-open when available because gtk_show_uri can inherit