authorgravatar for 132888838+arhxam@users.noreply.github.comArham Amin <132888838+arhxam@users.noreply.github.com> 2026-08-04 19:05:10+05:30
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-04 09:35:10-04:00
logc30a6d9b9943cfbf2fd47efc9de6eb9675457d52
tree5727cf57422667b961ba66178290444595fdfb5e
parent37ae1abbe947f0e002d008276225e4af2248a969
signature Signed by PGP key B5690EEEBB952194

fix(server): scrub AppImage XDG_DATA_DIRS and GSETTINGS_SCHEMA_DIR from terminals (#5075)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

2 files changed, 20 insertions(+), 4 deletions(-)

apps/server/src/terminal/Manager.test.ts+7
......@@ -1400,6 +1400,8 @@ it.layer(
14001400 OWD: "/home/user/project",
14011401 PATH: `${appDir}/usr/bin:${appDir}:/usr/local/bin:/usr/bin:/bin`,
14021402 LD_LIBRARY_PATH: `${appDir}/usr/lib:/home/user/.local/lib`,
1403 XDG_DATA_DIRS: `${appDir}/usr/share:/usr/local/share:/usr/share`,
1404 GSETTINGS_SCHEMA_DIR: `${appDir}/usr/share/glib-2.0/schemas`,
14031405 TEST_TERMINAL_KEEP: "keep-me",
14041406 },
14051407 });
......@@ -1419,6 +1421,11 @@ it.layer(
14191421 // mount segments that the runtime prepended.
14201422 expect(spawnInput.env.PATH).toBe("/usr/local/bin:/usr/bin:/bin");
14211423 expect(spawnInput.env.LD_LIBRARY_PATH).toBe("/home/user/.local/lib");
1424 // XDG_DATA_DIRS keeps the host entries but drops the AppImage share dir.
1425 expect(spawnInput.env.XDG_DATA_DIRS).toBe("/usr/local/share:/usr/share");
1426 // GSETTINGS_SCHEMA_DIR pointed only at the mount, so it is removed and
1427 // gsettings falls back to the host schema location.
1428 expect(spawnInput.env.GSETTINGS_SCHEMA_DIR).toBeUndefined();
14221429 // Unrelated host vars still pass through untouched.
14231430 expect(spawnInput.env.TEST_TERMINAL_KEEP).toBe("keep-me");
14241431 }),
apps/server/src/terminal/Manager.ts+13-4
......@@ -1097,10 +1097,19 @@ function shouldExcludeTerminalEnvKey(key: string): boolean {
10971097// They describe the AppImage itself, not the user's session, so terminals must
10981098// not inherit them.
10991099const APPIMAGE_RUNTIME_ENV_KEYS = ["APPIMAGE", "APPDIR", "ARGV0", "OWD"] as const;
1100// PATH-style variables the AppImage runtime prepends with its temporary mount
1101// (e.g. /tmp/.mount_T3-XXXX/usr/bin). Only the mount segments are dropped; the
1102// user's real entries are preserved.
1103const APPIMAGE_PATH_LIKE_ENV_KEYS = ["PATH", "LD_LIBRARY_PATH"] as const;
1100// Colon-separated search-path variables the AppImage runtime points at its
1101// temporary mount (e.g. /tmp/.mount_T3-XXXX/usr/bin, the bundled glib schemas,
1102// and an $APPDIR/usr/share XDG data entry). Only the mount segments are
1103// dropped; the user's real entries are preserved. When nothing but mount
1104// segments remain the variable is removed entirely so consumers fall back to
1105// their platform default (e.g. gsettings finds the host schemas instead of
1106// reporting "No schemas installed"). See issues #1699 and #5059.
1107const APPIMAGE_PATH_LIKE_ENV_KEYS = [
1108 "PATH",
1109 "LD_LIBRARY_PATH",
1110 "XDG_DATA_DIRS",
1111 "GSETTINGS_SCHEMA_DIR",
1112] as const;
11041113
11051114function isPathSegmentUnderAppDir(segment: string, appDir: string): boolean {
11061115 return segment === appDir || segment.startsWith(`${appDir}/`);