Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1f9a607

Browse files
author
Wahaj Ahmed
committed
fix: strip double quotes from sftp.args flags to prevent restic parse error
The UI constructs sftp.args flags with double-quoted paths (e.g. -i "/root/.ssh/key"), which causes restic's pflag parser to fail with 'bare " in non-quoted-field'. The sanitizeRepoFlags function now strips double quotes from sftp.args values since they are not needed when passed as sftp subcommand arguments. Fixes #1227
1 parent 39d9a3d commit 1f9a607

2 files changed

Lines changed: 59 additions & 1 deletion

File tree

internal/api/backresthandler.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,16 @@ func (s *BackrestHandler) GeneratePairingToken(ctx context.Context, req *connect
990990
func sanitizeRepoFlags(repo *v1.Repo) {
991991
for i, flag := range repo.Flags {
992992
if strings.HasPrefix(flag, "--option=sftp.args=") {
993-
repo.Flags[i] = strings.ReplaceAll(flag, "-i @", "-i ")
993+
// Remove the "-i @" workaround since we now handle quoting properly
994+
flag = strings.ReplaceAll(flag, "-i @", "-i ")
995+
// Strip double quotes from sftp.args values that cause restic's
996+
// pflag parser to fail with "bare \" in non-quoted-field".
997+
// The UI wraps paths in double quotes (e.g. -i "/path/to/key"),
998+
// but restic's --option flag parser cannot handle them.
999+
// Paths passed as sftp.args don't need quoting since they are
1000+
// passed directly to sftp as individual arguments.
1001+
flag = strings.ReplaceAll(flag, "\"", "")
1002+
repo.Flags[i] = flag
9941003
}
9951004
}
9961005
}

internal/api/backresthandler_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,3 +1123,52 @@ func getOperations(t *testing.T, log *oplog.OpLog) []*v1.Operation {
11231123
}
11241124
return operations
11251125
}
1126+
1127+
func TestSanitizeRepoFlags(t *testing.T) {
1128+
tests := []struct {
1129+
name string
1130+
flags []string
1131+
want []string
1132+
}{
1133+
{
1134+
name: "strip double quotes from sftp.args",
1135+
flags: []string{`--option=sftp.args='-oBatchMode=yes -i "/root/.ssh/id_ed25519" -p 23 -oUserKnownHostsFile="/root/.ssh/known_hosts"'`},
1136+
want: []string{`--option=sftp.args='-oBatchMode=yes -i /root/.ssh/id_ed25519 -p 23 -oUserKnownHostsFile=/root/.ssh/known_hosts'`},
1137+
},
1138+
{
1139+
name: "strip double quotes with -i @ workaround",
1140+
flags: []string{`--option=sftp.args='-oBatchMode=yes -i @/root/.ssh/id_ed25519"'`},
1141+
want: []string{`--option=sftp.args='-oBatchMode=yes -i /root/.ssh/id_ed25519'`},
1142+
},
1143+
{
1144+
name: "no sftp.args flags unchanged",
1145+
flags: []string{`--option=some.other=value`},
1146+
want: []string{`--option=some.other=value`},
1147+
},
1148+
{
1149+
name: "sftp.args without double quotes unchanged",
1150+
flags: []string{`--option=sftp.args=-oBatchMode=yes`},
1151+
want: []string{`--option=sftp.args=-oBatchMode=yes`},
1152+
},
1153+
{
1154+
name: "mixed flags only sftp.args modified",
1155+
flags: []string{`--option=other=val`, `--option=sftp.args='-i "/path/key"'`},
1156+
want: []string{`--option=other=val`, `--option=sftp.args=-i /path/key`},
1157+
},
1158+
}
1159+
1160+
for _, tt := range tests {
1161+
t.Run(tt.name, func(t *testing.T) {
1162+
repo := &v1.Repo{Flags: tt.flags}
1163+
sanitizeRepoFlags(repo)
1164+
if len(repo.Flags) != len(tt.want) {
1165+
t.Fatalf("got %d flags, want %d", len(repo.Flags), len(tt.want))
1166+
}
1167+
for i, got := range repo.Flags {
1168+
if got != tt.want[i] {
1169+
t.Errorf("flags[%d] = %q, want %q", i, got, tt.want[i])
1170+
}
1171+
}
1172+
})
1173+
}
1174+
}

0 commit comments

Comments
 (0)