mirror of
https://github.com/eugeny/tabby
synced 2026-09-27 15:35:52 +00:00
fix(local): resolve guest cwd against the shell's fsBase before validating (#11625)
Co-authored-by: Andrea Bergamasco <a.bergamasco@keesystem.com> Co-authored-by: Eugene <inbox@null.page>
This commit is contained in:
co-authored by
Andrea Bergamasco
Eugene
parent
034a76a853
commit
508dccc0b9
@@ -49,6 +49,13 @@ export class WSLShellProvider extends ShellProvider {
|
||||
return []
|
||||
}
|
||||
|
||||
// Windows path backing the distro's rootfs, so a POSIX cwd from the guest can be resolved.
|
||||
// Flags bit 3 marks a WSL2 distro (files served over \\wsl$); WSL1 lives under BasePath.
|
||||
const fsBaseForDistro = (key: any): string | undefined =>
|
||||
(key.Flags?.value || 0) & 8
|
||||
? `\\\\wsl$\\${key.DistributionName.value}`
|
||||
: key.BasePath ? key.BasePath.value + '\\rootfs' : undefined
|
||||
|
||||
const bashPath = `${process.env.windir}\\system32\\bash.exe`
|
||||
const wslPath = `${process.env.windir}\\system32\\wsl.exe`
|
||||
|
||||
@@ -59,6 +66,7 @@ export class WSLShellProvider extends ShellProvider {
|
||||
if (lxss?.DefaultDistribution) {
|
||||
const defaultDistKey = wnr.getRegistryKey(wnr.HK.CU, lxssPath + '\\' + String(lxss.DefaultDistribution.value))
|
||||
if (defaultDistKey?.DistributionName) {
|
||||
const name = defaultDistKey.DistributionName.value
|
||||
const shell: Shell = {
|
||||
id: 'wsl',
|
||||
name: 'WSL / Default distro',
|
||||
@@ -68,8 +76,9 @@ export class WSLShellProvider extends ShellProvider {
|
||||
COLORTERM: 'truecolor',
|
||||
},
|
||||
shellType: 'unix',
|
||||
fsBase: fsBaseForDistro(defaultDistKey),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
icon: wslIconMap[defaultDistKey.DistributionName.value] ?? wslIconMap.Linux,
|
||||
icon: wslIconMap[name] ?? wslIconMap.Linux,
|
||||
}
|
||||
shells.push(shell)
|
||||
}
|
||||
@@ -97,9 +106,8 @@ export class WSLShellProvider extends ShellProvider {
|
||||
if (!childKey.DistributionName || !childKey.BasePath) {
|
||||
continue
|
||||
}
|
||||
const wslVersion = (childKey.Flags?.value || 0) & 8 ? 2 : 1
|
||||
const name = childKey.DistributionName.value
|
||||
const fsBase = wslVersion === 2 ? `\\\\wsl$\\${name}` : childKey.BasePath.value as string + '\\rootfs'
|
||||
const fsBase = fsBaseForDistro(childKey)
|
||||
const slug = slugify(name, { remove: /[:.]/g })
|
||||
const shell: Shell = {
|
||||
id: `wsl-${slug}`,
|
||||
|
||||
@@ -46,6 +46,12 @@ export interface SessionOptions {
|
||||
shellType: ShellType | null
|
||||
pauseAfterExit: boolean
|
||||
runAsAdministrator: boolean
|
||||
|
||||
/**
|
||||
* Base path to which cwd is relative, e.g. `\\wsl$\Ubuntu` for WSL shells.
|
||||
* Used to translate a POSIX cwd reported by the guest shell into a real Windows path.
|
||||
*/
|
||||
fsBase: string | null
|
||||
}
|
||||
|
||||
export interface LocalProfile extends BaseTerminalProfile {
|
||||
|
||||
@@ -25,6 +25,7 @@ export class LocalProfilesService extends ProfileProvider<LocalProfile> {
|
||||
shellType: null,
|
||||
pauseAfterExit: false,
|
||||
runAsAdministrator: false,
|
||||
fsBase: null,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -84,6 +85,7 @@ export class LocalProfilesService extends ProfileProvider<LocalProfile> {
|
||||
env: shell.env,
|
||||
cwd: shell.cwd ?? null,
|
||||
shellType: shell.shellType ?? null,
|
||||
fsBase: shell.fsBase ?? null,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Injectable } from '@angular/core'
|
||||
import { Logger, LogService, ConfigService, ProfilesService, PartialProfile } from 'tabby-core'
|
||||
import { TerminalTabComponent } from '../components/terminalTab.component'
|
||||
import { LocalProfile } from '../api'
|
||||
import { resolveGuestCWD } from '../wslPath'
|
||||
import { isDirectorySync } from '../util'
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
@@ -37,7 +38,7 @@ export class TerminalService {
|
||||
|
||||
const fullProfile = this.profilesService.getConfigProxyForProfile(profile)
|
||||
|
||||
cwd = cwd ?? fullProfile.options.cwd
|
||||
cwd = resolveGuestCWD(cwd ?? fullProfile.options.cwd, fullProfile.options.fsBase)
|
||||
|
||||
if (cwd && !isDirectorySync(cwd)) {
|
||||
console.warn('Ignoring invalid CWD:', cwd)
|
||||
|
||||
@@ -4,6 +4,7 @@ import { HostAppService, ConfigService, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBui
|
||||
import { BaseSession } from 'tabby-terminal'
|
||||
import { SessionOptions, ChildProcess, PTYInterface, PTYProxy } from './api'
|
||||
import { getEnvironment, substituteEnv } from './environment'
|
||||
import { resolveGuestCWD } from './wslPath'
|
||||
import { isDirectory, isDirectorySync } from './util'
|
||||
|
||||
const windowsDirectoryRegex = /([a-zA-Z]:[^\:\[\]\?\"\<\>\|]+)/mi
|
||||
@@ -87,7 +88,7 @@ export class Session extends BaseSession {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
let cwd = options.cwd || process.env.HOME
|
||||
let cwd = resolveGuestCWD(options.cwd, options.fsBase) || process.env.HOME
|
||||
|
||||
if (!isDirectorySync(cwd)) {
|
||||
console.warn('Ignoring invalid CWD:', cwd)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { strictEqual } from 'assert'
|
||||
|
||||
/** Rewrite a POSIX guest cwd (e.g. WSL) to a Windows path via fsBase; unchanged otherwise. */
|
||||
export function resolveGuestCWD (cwd: string | null | undefined, fsBase: string | null | undefined): string | null | undefined {
|
||||
if (cwd?.startsWith('/') && fsBase) {
|
||||
return fsBase + cwd.replace(/\//g, '\\')
|
||||
}
|
||||
return cwd
|
||||
}
|
||||
|
||||
function selfCheck (): void {
|
||||
strictEqual(resolveGuestCWD('/home/x', '\\\\wsl$\\Ubuntu'), '\\\\wsl$\\Ubuntu\\home\\x')
|
||||
strictEqual(resolveGuestCWD('C:\\Users\\x', '\\\\wsl$\\Ubuntu'), 'C:\\Users\\x')
|
||||
strictEqual(resolveGuestCWD('/home/x', null), '/home/x')
|
||||
strictEqual(resolveGuestCWD(null, '\\\\wsl$\\Ubuntu'), null)
|
||||
strictEqual(resolveGuestCWD(undefined, null), undefined)
|
||||
}
|
||||
|
||||
// run: npx ts-node -O '{"module":"commonjs"}' tabby-local/src/wslPath.ts
|
||||
if (String(process.argv[1]).includes('wslPath')) {
|
||||
selfCheck()
|
||||
}
|
||||
Reference in New Issue
Block a user