perf: handle large ssh config alias lists (#3792)

This commit is contained in:
Neil
2026-05-30 10:26:37 -07:00
committed by GitHub
parent 27ec71970f
commit 662ebcbbd1
2 changed files with 46 additions and 3 deletions
+35
View File
@@ -6,6 +6,16 @@ vi.mock('os', () => ({
homedir: () => '/home/testuser'
}))
const LARGE_HOST_ALIAS_COUNT = 150_000
function buildHostAliases(count: number): string {
const aliases: string[] = []
for (let index = 0; index < count; index += 1) {
aliases.push(`generated-${index}`)
}
return aliases.join(' ')
}
describe('parseSshConfig', () => {
it('parses a basic host block', () => {
const config = `
@@ -172,6 +182,31 @@ Host staging stage *.example.com
])
})
it('parses large concrete alias lists on one Host line', () => {
const config = [
`Host ${buildHostAliases(LARGE_HOST_ALIAS_COUNT)}`,
' HostName generated.example.com',
'Host after',
' HostName after.example.com'
].join('\n')
const hosts = parseSshConfig(config)
expect(hosts).toHaveLength(LARGE_HOST_ALIAS_COUNT + 1)
expect(hosts[0]).toEqual({
host: 'generated-0',
hostname: 'generated.example.com'
})
expect(hosts[LARGE_HOST_ALIAS_COUNT - 1]).toEqual({
host: `generated-${LARGE_HOST_ALIAS_COUNT - 1}`,
hostname: 'generated.example.com'
})
expect(hosts.at(-1)).toEqual({
host: 'after',
hostname: 'after.example.com'
})
})
it('applies identity agent settings to every concrete alias on a multi-pattern Host line', () => {
const config = `
Host staging stage
+11 -3
View File
@@ -44,7 +44,7 @@ export function parseSshConfig(content: string): SshConfigHost[] {
if (key === 'host') {
if (current.length > 0) {
hosts.push(...current)
appendHosts(hosts, current)
}
const patterns = splitHostPatterns(value)
@@ -62,7 +62,7 @@ export function parseSshConfig(content: string): SshConfigHost[] {
if (key === 'match') {
if (current.length > 0) {
hosts.push(...current)
appendHosts(hosts, current)
}
current = []
continue
@@ -122,11 +122,19 @@ export function parseSshConfig(content: string): SshConfigHost[] {
}
if (current.length > 0) {
hosts.push(...current)
appendHosts(hosts, current)
}
return hosts
}
function appendHosts(target: SshConfigHost[], entries: SshConfigHost[]): void {
// Why: generated SSH configs can put many concrete aliases on one Host line;
// spreading that block into push can exceed JavaScript's argument limit.
for (const entry of entries) {
target.push(entry)
}
}
function splitHostPatterns(input: string): string[] {
const patterns: string[] = []
let current = ''