config: check config names more carefully and report errors - fixes #3506

Before this change it was possible to make a remote with an invalid
name in the config file, either manually or with `rclone config
create` (but not with `rclone config`).

When this remote was used, because it was invalid, rclone would
presume this remote name was a local directory for a very suprising
user experience!

This change checks remote names more carefully and returns errors
- when the user tries to use an invalid remote name on the command line
- when an invalid remote name is used in `rclone config create/update/password`
- when the user tries to enter an invalid remote name in `rclone config`

This does not prevent the user entering a remote name with invalid
characters in the config manually, but such a remote will fail
immediately when it is used on the command line.
This commit is contained in:
Nick Craig-Wood
2019-09-06 12:07:09 +01:00
parent 27a730ef8f
commit f1347139fa
6 changed files with 177 additions and 44 deletions
+15 -3
View File
@@ -944,6 +944,10 @@ func suppressConfirm() func() {
// UpdateRemote adds the keyValues passed in to the remote of name.
// keyValues should be key, value pairs.
func UpdateRemote(name string, keyValues rc.Params) error {
err := fspath.CheckConfigName(name)
if err != nil {
return err
}
defer suppressConfirm()()
// Work out which options need to be obscured
@@ -987,6 +991,10 @@ func UpdateRemote(name string, keyValues rc.Params) error {
// parameters which are key, value pairs. If update is set then it
// adds the new keys rather than replacing all of them.
func CreateRemote(name string, provider string, keyValues rc.Params) error {
err := fspath.CheckConfigName(name)
if err != nil {
return err
}
// Delete the old config if it exists
getConfigData().DeleteSection(name)
// Set the type
@@ -998,6 +1006,10 @@ func CreateRemote(name string, provider string, keyValues rc.Params) error {
// PasswordRemote adds the keyValues passed in to the remote of name.
// keyValues should be key, value pairs.
func PasswordRemote(name string, keyValues rc.Params) error {
err := fspath.CheckConfigName(name)
if err != nil {
return err
}
defer suppressConfirm()()
for k, v := range keyValues {
keyValues[k] = obscure.MustObscure(fmt.Sprint(v))
@@ -1041,14 +1053,14 @@ func NewRemoteName() (name string) {
for {
fmt.Printf("name> ")
name = ReadLine()
parts := fspath.Matcher.FindStringSubmatch(name + ":")
err := fspath.CheckConfigName(name)
switch {
case name == "":
fmt.Printf("Can't use empty name.\n")
case driveletter.IsDriveLetter(name):
fmt.Printf("Can't use %q as it can be confused with a drive letter.\n", name)
case parts == nil:
fmt.Printf("Can't use %q as it has invalid characters in it.\n", name)
case err != nil:
fmt.Printf("Can't use %q as %v.\n", name, err)
default:
return name
}