From a23ba4f14ef2ed43c3c7a7ace452d44c16adf2f9 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sat, 30 May 2026 05:08:59 -0700 Subject: [PATCH] fix: append ssh include lines without spread --- src/main/ssh/ssh-config-include-expander.ts | 10 +++++++++- src/main/ssh/ssh-config-loader.test.ts | 13 +++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/ssh/ssh-config-include-expander.ts b/src/main/ssh/ssh-config-include-expander.ts index b26b32b52c2..48f3629d6f2 100644 --- a/src/main/ssh/ssh-config-include-expander.ts +++ b/src/main/ssh/ssh-config-include-expander.ts @@ -64,7 +64,7 @@ function expandSshConfigFile( for (const includeArg of includeArgs) { for (const matchedPath of resolveIncludePaths(includeArg, context)) { - expandedLines.push(...expandSshConfigFile(matchedPath, context, nextStack)) + appendExpandedLines(expandedLines, expandSshConfigFile(matchedPath, context, nextStack)) } } } @@ -72,6 +72,14 @@ function expandSshConfigFile( return expandedLines } +function appendExpandedLines(target: string[], source: string[]): void { + // Why: valid include files can stay under the byte cap while still exceeding + // V8's argument limit if appended with `push(...source)`. + for (const line of source) { + target.push(line) + } +} + function readCachedFile(filePath: string, context: IncludeExpansionContext): string | null { const cached = context.cache.get(filePath) if (cached !== undefined) { diff --git a/src/main/ssh/ssh-config-loader.test.ts b/src/main/ssh/ssh-config-loader.test.ts index 316a4da050b..ae149d8b90f 100644 --- a/src/main/ssh/ssh-config-loader.test.ts +++ b/src/main/ssh/ssh-config-loader.test.ts @@ -100,6 +100,19 @@ describe('loadUserSshConfig', () => { expect(loadUserSshConfig().map((host) => host.host)).toEqual(['first', 'second']) }) + it('loads an include file with more lines than the JavaScript argument limit', () => { + const home = makeHome() + const manyCommentLines = Array.from({ length: 130_000 }, () => '#').join('\n') + writeFile( + home, + '.ssh/config', + 'Include many-comments.conf\nHost after\n HostName after.example.com\n' + ) + writeFile(home, '.ssh/many-comments.conf', manyCommentLines) + + expect(loadUserSshConfig().map((host) => host.host)).toEqual(['after']) + }) + it('supports relative includes, ${VAR}, and local % tokens', () => { const home = makeHome() process.env.ORCA_SSH_INCLUDE = 'from-env.conf'