drive: handle shared drives with leading/trailing space in name (related to #6618)
This commit is contained in:
parent
8b9f3bbe29
commit
5a59b49b6b
3 changed files with 51 additions and 30 deletions
|
@ -18,7 +18,6 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -3431,13 +3430,12 @@ func (f *Fs) Command(ctx context.Context, name string, arg []string, opt map[str
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
re := regexp.MustCompile(`[^\w\p{L}\p{N}. -]+`)
|
||||
if _, ok := opt["config"]; ok {
|
||||
lines := []string{}
|
||||
upstreams := []string{}
|
||||
names := make(map[string]struct{}, len(drives))
|
||||
for i, drive := range drives {
|
||||
name := re.ReplaceAllString(drive.Name, "_")
|
||||
name := fspath.MakeConfigName(drive.Name)
|
||||
for {
|
||||
if _, found := names[name]; !found {
|
||||
break
|
||||
|
|
|
@ -13,7 +13,8 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
configNameRe = `[\w\p{L}\p{N}.]+(?:[ -]+[\w\p{L}\p{N}.-]+)*` // don't allow it to start with `-` as it complicates usage (#4261)
|
||||
configNameRe = `[\w\p{L}\p{N}.]+(?:[ -]+[\w\p{L}\p{N}.-]+)*` // May contain Unicode numbers and letters, as well as `_`, `-`, `.` and space, but not start with `-` (it complicates usage, see #4261) or space, and not end with space
|
||||
illegalPartOfConfigNameRe = `^[ -]+|[^\w\p{L}\p{N}. -]+|[ ]+$`
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -32,6 +33,9 @@ var (
|
|||
// configNameMatcher is a pattern to match an rclone config name
|
||||
configNameMatcher = regexp.MustCompile(`^` + configNameRe + `$`)
|
||||
|
||||
// illegalPartOfConfigNameMatcher is a pattern to match a sequence of characters not allowed in an rclone config name
|
||||
illegalPartOfConfigNameMatcher = regexp.MustCompile(illegalPartOfConfigNameRe)
|
||||
|
||||
// remoteNameMatcher is a pattern to match an rclone remote name at the start of a config
|
||||
remoteNameMatcher = regexp.MustCompile(`^:?` + configNameRe + `(?::$|,)`)
|
||||
)
|
||||
|
@ -44,6 +48,21 @@ func CheckConfigName(configName string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// MakeConfigName makes an input into something legal to be used as a config name.
|
||||
// Returns a string where any sequences of illegal characters are replaced with
|
||||
// a single underscore. If the input is already valid as a config name, it is
|
||||
// returned unchanged. If the input is an empty string, a single underscore is
|
||||
// returned.
|
||||
func MakeConfigName(name string) string {
|
||||
if name == "" {
|
||||
return "_"
|
||||
}
|
||||
if configNameMatcher.MatchString(name) {
|
||||
return name
|
||||
}
|
||||
return illegalPartOfConfigNameMatcher.ReplaceAllString(name, "_")
|
||||
}
|
||||
|
||||
// checkRemoteName returns an error if remoteName is invalid
|
||||
func checkRemoteName(remoteName string) error {
|
||||
if remoteName == ":" || remoteName == "::" {
|
||||
|
|
|
@ -19,34 +19,38 @@ var (
|
|||
|
||||
func TestCheckConfigName(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
want error
|
||||
in string
|
||||
problem error
|
||||
fixed string
|
||||
}{
|
||||
{"remote", nil},
|
||||
{"REMOTE", nil},
|
||||
{"", errInvalidCharacters},
|
||||
{":remote:", errInvalidCharacters},
|
||||
{"remote:", errInvalidCharacters},
|
||||
{"rem:ote", errInvalidCharacters},
|
||||
{"rem/ote", errInvalidCharacters},
|
||||
{"rem\\ote", errInvalidCharacters},
|
||||
{"[remote", errInvalidCharacters},
|
||||
{"*", errInvalidCharacters},
|
||||
{"-remote", errInvalidCharacters},
|
||||
{"r-emote-", nil},
|
||||
{"_rem_ote_", nil},
|
||||
{".", nil},
|
||||
{"..", nil},
|
||||
{".r.e.m.o.t.e.", nil},
|
||||
{"rem ote", nil},
|
||||
{"blåbær", nil},
|
||||
{"chữ Quốc ngữ", nil},
|
||||
{"remote ", errInvalidCharacters},
|
||||
{" remote", errInvalidCharacters},
|
||||
{" remote ", errInvalidCharacters},
|
||||
{"remote", nil, "remote"},
|
||||
{"REMOTE", nil, "REMOTE"},
|
||||
{"", errInvalidCharacters, "_"},
|
||||
{":remote:", errInvalidCharacters, "_remote_"},
|
||||
{"remote:", errInvalidCharacters, "remote_"},
|
||||
{"rem:ote", errInvalidCharacters, "rem_ote"},
|
||||
{"rem/ote", errInvalidCharacters, "rem_ote"},
|
||||
{"rem\\ote", errInvalidCharacters, "rem_ote"},
|
||||
{"[remote", errInvalidCharacters, "_remote"},
|
||||
{"*", errInvalidCharacters, "_"},
|
||||
{"-remote", errInvalidCharacters, "_remote"},
|
||||
{"r-emote-", nil, "r-emote-"},
|
||||
{"---rem:::ote???", errInvalidCharacters, "_rem_ote_"},
|
||||
{"_rem_ote_", nil, "_rem_ote_"},
|
||||
{".", nil, "."},
|
||||
{"..", nil, ".."},
|
||||
{".r.e.m.o.t.e.", nil, ".r.e.m.o.t.e."},
|
||||
{"rem ote", nil, "rem ote"},
|
||||
{"blåbær", nil, "blåbær"},
|
||||
{"chữ Quốc ngữ", nil, "chữ Quốc ngữ"},
|
||||
{"remote ", errInvalidCharacters, "remote_"},
|
||||
{" remote", errInvalidCharacters, "_remote"},
|
||||
{" remote ", errInvalidCharacters, "_remote_"},
|
||||
} {
|
||||
got := CheckConfigName(test.in)
|
||||
assert.Equal(t, test.want, got, test.in)
|
||||
problem := CheckConfigName(test.in)
|
||||
assert.Equal(t, test.problem, problem, test.in)
|
||||
fixed := MakeConfigName(test.in)
|
||||
assert.Equal(t, test.fixed, fixed, test.in)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue