Skip to content

Commit 13cbb99

Browse files
authored
Merge pull request #97 from arixmkii/fix-windows-escape
Make argument quotation compatible with cygwin/msys2/gitbash on Windows
2 parents 4e31f25 + f469c85 commit 13cbb99

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

.github/workflows/main.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
matrix:
1212
go-version: [1.23.x, 1.24.x]
13-
platform: [ubuntu-latest, macos-latest]
13+
platform: [ubuntu-latest, macos-latest, windows-latest]
1414
runs-on: ${{ matrix.platform }}
1515
steps:
1616
- uses: actions/checkout@v4
@@ -20,5 +20,6 @@ jobs:
2020
with:
2121
go-version: ${{ matrix.go-version }}
2222
- run: make
23-
- run: sudo make install
23+
- if: "${{ matrix.platform != 'windows-latest' }}"
24+
run: sudo make install
2425
- run: go test -covermode=atomic -race -v ./...

pkg/reversesshfs/reversesshfs.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (rsf *ReverseSSHFS) Prepare() error {
5252
sshArgs = append(sshArgs, "-p", strconv.Itoa(rsf.Port))
5353
}
5454
sshArgs = append(sshArgs, rsf.Host, "--")
55-
sshArgs = append(sshArgs, "mkdir", "-p", strconv.Quote(rsf.RemotePath))
55+
sshArgs = append(sshArgs, "mkdir", "-p", addQuotes(rsf.RemotePath))
5656
sshCmd := exec.Command(sshBinary, sshArgs...)
5757
logrus.Debugf("executing ssh for preparing sshfs: %s %v", sshCmd.Path, sshCmd.Args)
5858
out, err := sshCmd.CombinedOutput()
@@ -141,7 +141,7 @@ func (rsf *ReverseSSHFS) Start() error {
141141
sshArgs = append(sshArgs, "-p", strconv.Itoa(rsf.Port))
142142
}
143143
sshArgs = append(sshArgs, rsf.Host, "--")
144-
sshArgs = append(sshArgs, "sshfs", strconv.Quote(":"+rsf.LocalPath), strconv.Quote(rsf.RemotePath), "-o", "slave")
144+
sshArgs = append(sshArgs, "sshfs", addQuotes(":"+rsf.LocalPath), addQuotes(rsf.RemotePath), "-o", "slave")
145145
if rsf.Readonly {
146146
sshArgs = append(sshArgs, "-o", "ro")
147147
}
@@ -252,6 +252,18 @@ func (rsf *ReverseSSHFS) Start() error {
252252
return nil
253253
}
254254

255+
func addQuotes(input string) string {
256+
input = strconv.Quote(input)
257+
// exec.Command on Windows would escape wrapping double quotes in a way, which is not compatible
258+
// with passing arguments into bash shell over ssh, replacing with single quotes as a workaround.
259+
if runtime.GOOS == "windows" {
260+
input = strings.TrimPrefix(input, "\"")
261+
input = strings.TrimSuffix(input, "\"")
262+
return fmt.Sprintf(`'%s'`, input)
263+
}
264+
return input
265+
}
266+
255267
func (rsf *ReverseSSHFS) waitForRemoteReady() error {
256268
scriptName := "wait-for-remote-ready"
257269
scriptTemplate := `#!/bin/sh

pkg/reversesshfs/reversesshfs_test.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package reversesshfs
2+
3+
import (
4+
"runtime"
5+
"testing"
6+
)
7+
8+
func TestAddQuotes(t *testing.T) {
9+
type testCase struct {
10+
input string
11+
expected string
12+
}
13+
var testCases []testCase
14+
if runtime.GOOS != "windows" {
15+
testCases = []testCase{
16+
{
17+
input: "/user/test/path",
18+
expected: "\"/user/test/path\"",
19+
},
20+
}
21+
} else {
22+
testCases = []testCase{
23+
{
24+
input: "/user/test/path",
25+
expected: "'/user/test/path'",
26+
},
27+
}
28+
}
29+
for i, tc := range testCases {
30+
got := addQuotes(tc.input)
31+
if got != tc.expected {
32+
t.Errorf("#%d: expected %q, got %q", i, tc.expected, got)
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)