Skip to content

Commit 637ec6b

Browse files
wesmclaude
andcommitted
Restrict CLI quote stripping to Windows only
On Unix, shells strip quotes before the process sees them, and literal quote characters in paths are valid (if unusual). Guard the stripping with runtime.GOOS == "windows" and mark the corresponding tests as windowsOnly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c0bd3d4 commit 637ec6b

File tree

2 files changed

+24
-14
lines changed

2 files changed

+24
-14
lines changed

internal/config/config.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"log/slog"
77
"os"
88
"path/filepath"
9+
"runtime"
910
"strings"
1011

1112
"github.com/BurntSushi/toml"
@@ -244,7 +245,9 @@ func expandPath(path string) string {
244245
return path
245246
}
246247
// Strip surrounding quotes left by Windows CMD (e.g. --home 'C:\Users\foo').
247-
if len(path) >= 2 &&
248+
// Only on Windows — Unix shells strip quotes before the process sees them,
249+
// and literal quote characters in Unix paths are valid (if unusual).
250+
if runtime.GOOS == "windows" && len(path) >= 2 &&
248251
((path[0] == '\'' && path[len(path)-1] == '\'') ||
249252
(path[0] == '"' && path[len(path)-1] == '"')) {
250253
path = path[1 : len(path)-1]

internal/config/config_test.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ func TestExpandPath(t *testing.T) {
1515
}
1616

1717
tests := []struct {
18-
name string
19-
input string
20-
expected string
21-
unixOnly bool // skip on Windows (uses Unix-style absolute paths)
18+
name string
19+
input string
20+
expected string
21+
unixOnly bool // skip on Windows (uses Unix-style absolute paths)
22+
windowsOnly bool // skip on non-Windows (quote stripping is Windows-only)
2223
}{
2324
{
2425
name: "empty string",
@@ -51,19 +52,22 @@ func TestExpandPath(t *testing.T) {
5152
expected: filepath.Join(home, "foo"),
5253
},
5354
{
54-
name: "single-quoted path (Windows CMD)",
55-
input: `'C:\Users\wesmc\testing'`,
56-
expected: `C:\Users\wesmc\testing`,
55+
name: "single-quoted path (Windows CMD)",
56+
input: `'C:\Users\wesmc\testing'`,
57+
expected: `C:\Users\wesmc\testing`,
58+
windowsOnly: true,
5759
},
5860
{
59-
name: "double-quoted path (Windows CMD)",
60-
input: `"C:\Users\wesmc\testing"`,
61-
expected: `C:\Users\wesmc\testing`,
61+
name: "double-quoted path (Windows CMD)",
62+
input: `"C:\Users\wesmc\testing"`,
63+
expected: `C:\Users\wesmc\testing`,
64+
windowsOnly: true,
6265
},
6366
{
64-
name: "single-quoted tilde path",
65-
input: "'~/custom-data'",
66-
expected: filepath.Join(home, "custom-data"),
67+
name: "single-quoted tilde path",
68+
input: "'~/custom-data'",
69+
expected: filepath.Join(home, "custom-data"),
70+
windowsOnly: true,
6771
},
6872
{
6973
name: "mismatched quotes not stripped",
@@ -104,6 +108,9 @@ func TestExpandPath(t *testing.T) {
104108
if tt.unixOnly && runtime.GOOS == "windows" {
105109
t.Skip("skipping Unix-specific path test on Windows")
106110
}
111+
if tt.windowsOnly && runtime.GOOS != "windows" {
112+
t.Skip("skipping Windows-specific path test on non-Windows")
113+
}
107114
got := expandPath(tt.input)
108115
if got != tt.expected {
109116
t.Errorf("expandPath(%q) = %q, want %q", tt.input, got, tt.expected)

0 commit comments

Comments
 (0)