mirror of
https://github.com/octoleo/restic.git
synced 2024-11-02 11:46:36 +00:00
Merge pull request #1070 from restic/warn-unsupported-repo-type
Return an error for invalid backend schemes
This commit is contained in:
commit
390e2bbddc
@ -10,6 +10,7 @@ import (
|
|||||||
"restic/backend/s3"
|
"restic/backend/s3"
|
||||||
"restic/backend/sftp"
|
"restic/backend/sftp"
|
||||||
"restic/backend/swift"
|
"restic/backend/swift"
|
||||||
|
"restic/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Location specifies the location of a repository, including the method of
|
// Location specifies the location of a repository, including the method of
|
||||||
@ -35,6 +36,36 @@ var parsers = []parser{
|
|||||||
{"rest", rest.ParseConfig},
|
{"rest", rest.ParseConfig},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isPath(s string) bool {
|
||||||
|
if strings.HasPrefix(s, "../") || strings.HasPrefix(s, `..\`) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(s, "/") || strings.HasPrefix(s, `\`) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s) < 3 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for drive paths
|
||||||
|
drive := s[0]
|
||||||
|
if !(drive >= 'a' && drive <= 'z') && !(drive >= 'A' && drive <= 'Z') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if s[1] != ':' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if s[2] != '\\' && s[2] != '/' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Parse extracts repository location information from the string s. If s
|
// Parse extracts repository location information from the string s. If s
|
||||||
// starts with a backend name followed by a colon, that backend's Parse()
|
// starts with a backend name followed by a colon, that backend's Parse()
|
||||||
// function is called. Otherwise, the local backend is used which interprets s
|
// function is called. Otherwise, the local backend is used which interprets s
|
||||||
@ -56,7 +87,11 @@ func Parse(s string) (u Location, err error) {
|
|||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// try again, with the local parser and the prefix "local:"
|
// if s is not a path or contains ":", it's ambiguous
|
||||||
|
if !isPath(s) && strings.ContainsRune(s, ':') {
|
||||||
|
return Location{}, errors.New("invalid backend\nIf the repo is in a local directory, you need to add a `local:` prefix")
|
||||||
|
}
|
||||||
|
|
||||||
u.Scheme = "local"
|
u.Scheme = "local"
|
||||||
u.Config, err = local.ParseConfig("local:" + s)
|
u.Config, err = local.ParseConfig("local:" + s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -58,6 +58,14 @@ var parseTests = []struct {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"/dir1/dir2",
|
||||||
|
Location{Scheme: "local",
|
||||||
|
Config: local.Config{
|
||||||
|
Path: "/dir1/dir2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"local:../dir1/dir2",
|
"local:../dir1/dir2",
|
||||||
Location{Scheme: "local",
|
Location{Scheme: "local",
|
||||||
@ -74,7 +82,46 @@ var parseTests = []struct {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"/dir1:foobar/dir2",
|
||||||
|
Location{Scheme: "local",
|
||||||
|
Config: local.Config{
|
||||||
|
Path: "/dir1:foobar/dir2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`\dir1\foobar\dir2`,
|
||||||
|
Location{Scheme: "local",
|
||||||
|
Config: local.Config{
|
||||||
|
Path: `\dir1\foobar\dir2`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`c:\dir1\foobar\dir2`,
|
||||||
|
Location{Scheme: "local",
|
||||||
|
Config: local.Config{
|
||||||
|
Path: `c:\dir1\foobar\dir2`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`C:\Users\appveyor\AppData\Local\Temp\1\restic-test-879453535\repo`,
|
||||||
|
Location{Scheme: "local",
|
||||||
|
Config: local.Config{
|
||||||
|
Path: `C:\Users\appveyor\AppData\Local\Temp\1\restic-test-879453535\repo`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`c:/dir1/foobar/dir2`,
|
||||||
|
Location{Scheme: "local",
|
||||||
|
Config: local.Config{
|
||||||
|
Path: `c:/dir1/foobar/dir2`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"sftp:user@host:/srv/repo",
|
"sftp:user@host:/srv/repo",
|
||||||
Location{Scheme: "sftp",
|
Location{Scheme: "sftp",
|
||||||
@ -274,3 +321,19 @@ func TestParse(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInvalidScheme(t *testing.T) {
|
||||||
|
var invalidSchemes = []string{
|
||||||
|
"foobar:xxx",
|
||||||
|
"foobar:/dir/dir2",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range invalidSchemes {
|
||||||
|
t.Run(s, func(t *testing.T) {
|
||||||
|
_, err := Parse(s)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("error for invalid location %q not found", s)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user