fix: open host URLs with a clean environment (triple-c#34)
On Linux the app ships as a single AppImage, and the AppImage environment leaks into everything it spawns. linuxdeploy's AppRun, linuxdeploy-plugin-gtk and our own wayland fallback hook all export LD_LIBRARY_PATH, GTK_PATH, GIO_MODULE_DIR and friends pointing inside $APPDIR, and main.rs sets WEBKIT_DISABLE_DMABUF_RENDERER process-wide for the webview. A browser that is already running shrugs this off, because xdg-open just hands the URL to the existing process. A cold-launched one inherits the lot and dies before painting -- with xdg-open still exiting 0, which is why this looked like the button doing nothing at all. `url_open` captures a pristine snapshot of the environment in main() before any mutation runs, then hands children a repaired copy: a saved original is restored where one exists, otherwise the process-start value is restored where we changed it, otherwise only the colon-separated entries that live under $APPDIR are dropped and the user's own are kept. Outside an AppImage it is a no-op. The command re-validates the URL in Rust rather than trusting the frontend, because the URL originates in an untrusted container: http/https only, no embedded credentials, no control characters or whitespace, length capped, ASCII asserted before it reaches execvp, and error messages never echo the input. Spawning is Command with explicit args and never a shell, trying xdg-open then gio open. No portal. org.freedesktop.portal.OpenURI would pull in a D-Bus client stack for one call on the one platform where we ship self-contained, and it only helps where a portal is running -- the same case where xdg-open already works once the environment is clean. `gio open` as a second candidate recovers most of the missing-MIME-association case for free. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -63,6 +63,12 @@
|
||||
/// URL; most non-WebKitGTK browsers ignore the variable entirely), but
|
||||
/// worth knowing before chasing the "links don't open" half of triple-c#34
|
||||
/// as a separate, unrelated cause.
|
||||
///
|
||||
/// That leak is now plugged rather than merely documented: `url_open` hands
|
||||
/// the opener a child environment with this variable (and the AppImage's own
|
||||
/// `LD_LIBRARY_PATH`/`GTK_PATH`/... ) restored or removed. Setting it here
|
||||
/// stays process-wide because GTK/WebKitGTK need it; what changed is that the
|
||||
/// children no longer inherit it.
|
||||
#[cfg(target_os = "linux")]
|
||||
const DMABUF_VAR: &str = "WEBKIT_DISABLE_DMABUF_RENDERER";
|
||||
|
||||
@@ -138,6 +144,12 @@ mod tests {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Before *any* `std::env::set_var` — `url_open` hands a child process the
|
||||
// environment this app was started with, and the workaround below is one
|
||||
// of the things that must not leak into it (see triple-c#34). Anything
|
||||
// added here that mutates the environment belongs after this line.
|
||||
triple_c_lib::url_open::capture_pristine_environment();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
apply_webkit_wayland_workaround();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user