1
mirror of https://github.com/rclone/rclone synced 2024-07-27 16:38:21 +02:00

sftp: fix hashes of files with backslashes

This commit is contained in:
Nick Craig-Wood 2019-07-26 12:19:47 +01:00
parent 00b2c02bf4
commit b90e4a8769

View File

@ -950,6 +950,7 @@ func (o *Object) Hash(ctx context.Context, r hash.Type) (string, error) {
escapedPath = shellEscape(path.Join(o.fs.opt.PathOverride, o.remote)) escapedPath = shellEscape(path.Join(o.fs.opt.PathOverride, o.remote))
} }
err = session.Run(hashCmd + " " + escapedPath) err = session.Run(hashCmd + " " + escapedPath)
fs.Debugf(nil, "sftp cmd = %s", escapedPath)
if err != nil { if err != nil {
_ = session.Close() _ = session.Close()
fs.Debugf(o, "Failed to calculate %v hash: %v (%s)", r, err, bytes.TrimSpace(stderr.Bytes())) fs.Debugf(o, "Failed to calculate %v hash: %v (%s)", r, err, bytes.TrimSpace(stderr.Bytes()))
@ -957,7 +958,10 @@ func (o *Object) Hash(ctx context.Context, r hash.Type) (string, error) {
} }
_ = session.Close() _ = session.Close()
str := parseHash(stdout.Bytes()) b := stdout.Bytes()
fs.Debugf(nil, "sftp output = %q", b)
str := parseHash(b)
fs.Debugf(nil, "sftp hash = %q", str)
if r == hash.MD5 { if r == hash.MD5 {
o.md5sum = &str o.md5sum = &str
} else if r == hash.SHA1 { } else if r == hash.SHA1 {
@ -966,7 +970,7 @@ func (o *Object) Hash(ctx context.Context, r hash.Type) (string, error) {
return str, nil return str, nil
} }
var shellEscapeRegex = regexp.MustCompile(`[^A-Za-z0-9_.,:/@\n-]`) var shellEscapeRegex = regexp.MustCompile("[^A-Za-z0-9_.,:/\\@\u0080-\uFFFFFFFF\n-]")
// Escape a string s.t. it cannot cause unintended behavior // Escape a string s.t. it cannot cause unintended behavior
// when sending it to a shell. // when sending it to a shell.
@ -979,7 +983,9 @@ func shellEscape(str string) string {
// an invocation of md5sum/sha1sum to a hash string // an invocation of md5sum/sha1sum to a hash string
// as expected by the rest of this application // as expected by the rest of this application
func parseHash(bytes []byte) string { func parseHash(bytes []byte) string {
return strings.Split(string(bytes), " ")[0] // Split at hash / filename separator // For strings with backslash *sum writes a leading \
// https://unix.stackexchange.com/q/313733/94054
return strings.Split(strings.TrimLeft(string(bytes), "\\"), " ")[0] // Split at hash / filename separator
} }
// Parses the byte array output from the SSH session // Parses the byte array output from the SSH session