Skip to content

Commit d80e482

Browse files
committed
Handle spaces when concatenating environment variables
1 parent 1d8e441 commit d80e482

File tree

3 files changed

+30
-26
lines changed

3 files changed

+30
-26
lines changed

src/remote/remote.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import {
4444
SSHConfig,
4545
type SSHValues,
4646
mergeSshConfigValues,
47-
parseSshConfig as parseSshConfig,
47+
parseSshConfig,
4848
} from "./sshConfig";
4949
import { SshProcessMonitor } from "./sshProcess";
5050
import { computeSSHProperties, sshSupportsSetEnv } from "./sshSupport";
@@ -769,7 +769,7 @@ export class Remote {
769769
if (sshSupportsSetEnv()) {
770770
// This allows for tracking the number of extension
771771
// users connected to workspaces!
772-
sshValues.SetEnv = " CODER_SSH_SESSION_TYPE=vscode";
772+
sshValues.SetEnv = "CODER_SSH_SESSION_TYPE=vscode";
773773
}
774774

775775
await sshConfig.update(label, sshValues, sshConfigOverrides);

src/remote/sshConfig.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function parseSshConfig(lines: string[]): Record<string, string> {
5151
}
5252

5353
const key = keyMatch[0];
54-
const separator = line[key.length];
54+
const separator = line.at(key.length);
5555
if (separator !== "=" && separator !== " ") {
5656
return acc; // Malformed line
5757
}
@@ -63,7 +63,7 @@ export function parseSshConfig(lines: string[]): Record<string, string> {
6363
// Ignore empty SetEnv values
6464
if (value !== "") {
6565
const existing = acc["SetEnv"];
66-
acc["SetEnv"] = existing ? `${existing} ${value}` : ` ${value}`;
66+
acc["SetEnv"] = existing ? `${existing} ${value}` : value;
6767
}
6868
} else {
6969
acc[key] = value;
@@ -102,7 +102,11 @@ export function mergeSshConfigValues(
102102

103103
// Special handling for SetEnv - concatenate values instead of replacing.
104104
if (lower === "setenv") {
105-
merged["SetEnv"] = `${config[key]}${value}`;
105+
if (value === "") {
106+
merged["SetEnv"] = config[key];
107+
} else {
108+
merged["SetEnv"] = `${config[key]} ${value}`;
109+
}
106110
return;
107111
}
108112

@@ -126,7 +130,7 @@ export function mergeSshConfigValues(
126130

127131
// Special handling for SetEnv - concatenate if already exists
128132
if (lower === "setenv" && merged["SetEnv"]) {
129-
merged["SetEnv"] = `${merged["SetEnv"]}${value}`;
133+
merged["SetEnv"] = `${merged["SetEnv"]} ${value}`;
130134
} else {
131135
merged[correctCaseKey] = value;
132136
}

test/unit/remote/sshConfig.test.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -738,17 +738,17 @@ describe("parseSshConfig", () => {
738738
{
739739
name: "SetEnv with space",
740740
input: ["SetEnv MY_VAR=value OTHER_VAR=othervalue"],
741-
expected: { SetEnv: " MY_VAR=value OTHER_VAR=othervalue" },
741+
expected: { SetEnv: "MY_VAR=value OTHER_VAR=othervalue" },
742742
},
743743
{
744744
name: "SetEnv with equals",
745745
input: ["SetEnv=MY_VAR=value OTHER_VAR=othervalue"],
746-
expected: { SetEnv: " MY_VAR=value OTHER_VAR=othervalue" },
746+
expected: { SetEnv: "MY_VAR=value OTHER_VAR=othervalue" },
747747
},
748748
{
749749
name: "accumulates SetEnv entries",
750750
input: ["SetEnv A=1", "setenv B=2 C=3"],
751-
expected: { SetEnv: " A=1 B=2 C=3" },
751+
expected: { SetEnv: "A=1 B=2 C=3" },
752752
},
753753
{
754754
name: "skips malformed lines",
@@ -763,12 +763,12 @@ describe("parseSshConfig", () => {
763763
{
764764
name: "quoted value with spaces",
765765
input: ['SetEnv key="Hello world"'],
766-
expected: { SetEnv: ' key="Hello world"' },
766+
expected: { SetEnv: 'key="Hello world"' },
767767
},
768768
{
769769
name: "multiple keys",
770770
input: ["ConnectTimeout 10", "LogLevel=DEBUG", "SetEnv VAR=1"],
771-
expected: { ConnectTimeout: "10", LogLevel: "DEBUG", SetEnv: " VAR=1" },
771+
expected: { ConnectTimeout: "10", LogLevel: "DEBUG", SetEnv: "VAR=1" },
772772
},
773773
{
774774
name: "ignores empty SetEnv",
@@ -815,39 +815,39 @@ describe("mergeSshConfigValues", () => {
815815
},
816816
{
817817
name: "concatenates SetEnv values",
818-
config: { SetEnv: " A=1" },
819-
overrides: { SetEnv: " B=2" },
820-
expected: { SetEnv: " A=1 B=2" },
818+
config: { SetEnv: "A=1" },
819+
overrides: { SetEnv: "B=2" },
820+
expected: { SetEnv: "A=1 B=2" },
821821
},
822822
{
823823
name: "concatenates SetEnv case-insensitively",
824-
config: { SetEnv: " A=1" },
825-
overrides: { setenv: " B=2" },
826-
expected: { SetEnv: " A=1 B=2" },
824+
config: { SetEnv: "A=1" },
825+
overrides: { setenv: "B=2" },
826+
expected: { SetEnv: "A=1 B=2" },
827827
},
828828
{
829829
name: "SetEnv only in override",
830830
config: {},
831-
overrides: { SetEnv: " B=2" },
832-
expected: { SetEnv: " B=2" },
831+
overrides: { SetEnv: "B=2" },
832+
expected: { SetEnv: "B=2" },
833833
},
834834
{
835835
name: "SetEnv only in config",
836-
config: { SetEnv: " A=1" },
836+
config: { SetEnv: "A=1" },
837837
overrides: {},
838-
expected: { SetEnv: " A=1" },
838+
expected: { SetEnv: "A=1" },
839839
},
840840
{
841841
name: "SetEnv with other values",
842-
config: { SetEnv: " A=1", LogLevel: "ERROR" },
843-
overrides: { SetEnv: " B=2", Timeout: "10" },
844-
expected: { SetEnv: " A=1 B=2", LogLevel: "ERROR", Timeout: "10" },
842+
config: { SetEnv: "A=1", LogLevel: "ERROR" },
843+
overrides: { SetEnv: "B=2", Timeout: "10" },
844+
expected: { SetEnv: "A=1 B=2", LogLevel: "ERROR", Timeout: "10" },
845845
},
846846
{
847847
name: "ignores empty SetEnv override",
848-
config: { SetEnv: " A=1 B=2" },
848+
config: { SetEnv: "A=1 B=2" },
849849
overrides: { SetEnv: "" },
850-
expected: { SetEnv: " A=1 B=2" },
850+
expected: { SetEnv: "A=1 B=2" },
851851
},
852852
])("$name", ({ config, overrides, expected }) => {
853853
expect(mergeSshConfigValues(config, overrides)).toEqual(expected);

0 commit comments

Comments
 (0)