mirror of
https://github.com/rclone/rclone.git
synced 2024-11-07 09:04:52 +01:00
local: fix encoding of root path
fix #7824 Statements like rclone copy <somewhere> . will spontaneously miss if . expands to a path with a Full Width replacement character. This is due to the incorrect order in which relative paths and decoding were handled in the original implementation.
This commit is contained in:
parent
2a615f4681
commit
e1b7bf7701
@ -1568,34 +1568,49 @@ func (o *Object) SetMetadata(ctx context.Context, metadata fs.Metadata) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func cleanRootPath(s string, noUNC bool, enc encoder.MultiEncoder) string {
|
func cleanRootPath(s string, noUNC bool, enc encoder.MultiEncoder) string {
|
||||||
if runtime.GOOS != "windows" || !strings.HasPrefix(s, "\\") {
|
var vol string
|
||||||
if !filepath.IsAbs(s) {
|
|
||||||
s2, err := filepath.Abs(s)
|
|
||||||
if err == nil {
|
|
||||||
s = s2
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
s = filepath.Clean(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
s = filepath.ToSlash(s)
|
vol = filepath.VolumeName(s)
|
||||||
vol := filepath.VolumeName(s)
|
|
||||||
if vol == `\\?` && len(s) >= 6 {
|
if vol == `\\?` && len(s) >= 6 {
|
||||||
// `\\?\C:`
|
// `\\?\C:`
|
||||||
vol = s[:6]
|
vol = s[:6]
|
||||||
}
|
}
|
||||||
s = vol + enc.FromStandardPath(s[len(vol):])
|
s = s[len(vol):]
|
||||||
|
}
|
||||||
|
// Don't use FromStandardPath. Make sure Dot (`.`, `..`) as name will not be reencoded
|
||||||
|
// Take care of the case Standard: ././‛. (the first dot means current directory)
|
||||||
|
if enc != encoder.Standard {
|
||||||
|
s = filepath.ToSlash(s)
|
||||||
|
parts := strings.Split(s, "/")
|
||||||
|
encoded := make([]string, len(parts))
|
||||||
|
changed := false
|
||||||
|
for i, p := range parts {
|
||||||
|
if (p == ".") || (p == "..") {
|
||||||
|
encoded[i] = p
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
part := enc.FromStandardName(p)
|
||||||
|
changed = changed || part != p
|
||||||
|
encoded[i] = part
|
||||||
|
}
|
||||||
|
if changed {
|
||||||
|
s = strings.Join(encoded, "/")
|
||||||
|
}
|
||||||
s = filepath.FromSlash(s)
|
s = filepath.FromSlash(s)
|
||||||
|
}
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
s = vol + s
|
||||||
|
}
|
||||||
|
s2, err := filepath.Abs(s)
|
||||||
|
if err == nil {
|
||||||
|
s = s2
|
||||||
|
}
|
||||||
if !noUNC {
|
if !noUNC {
|
||||||
// Convert to UNC
|
// Convert to UNC. It does nothing on non windows platforms.
|
||||||
s = file.UNCPath(s)
|
s = file.UNCPath(s)
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
s = enc.FromStandardPath(s)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// Items returns the count of items in this directory or this
|
// Items returns the count of items in this directory or this
|
||||||
// directory and subdirectories if known, -1 for unknown
|
// directory and subdirectories if known, -1 for unknown
|
||||||
|
Loading…
Reference in New Issue
Block a user