Merge pull request #3691 from greatroar/tag-filenames

Sanitize tags when used as filenames by restic mount
This commit is contained in:
MichaelEischer 2022-08-19 18:33:44 +02:00 committed by GitHub
commit b4dfab002a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 0 deletions

View file

@ -6,5 +6,10 @@ formatting of the time for a snapshot is now controlled using `--time-template`
and supports subdirectories to for example group snapshots by year. Please
refer to the help output of the `mount` command for further details.
Characters in tag names which are not allowed in a filename are replaced by
underscores `_`. For example a tag `foo/bar` will result in a directory name
of `foo_bar`.
https://github.com/restic/restic/issues/2907
https://github.com/restic/restic/pull/2913
https://github.com/restic/restic/pull/3691

View file

@ -97,6 +97,7 @@ func pathsFromSn(pathTemplate string, timeTemplate string, sn *restic.Snapshot)
// needs special treatment: Rebuild the string builders
newout := make([]strings.Builder, len(out)*len(sn.Tags))
for i, tag := range sn.Tags {
tag = filenameFromTag(tag)
for j := range out {
newout[i*len(out)+j].WriteString(out[j].String() + tag)
}
@ -139,6 +140,24 @@ func pathsFromSn(pathTemplate string, timeTemplate string, sn *restic.Snapshot)
return paths, timeSuffix
}
// Some tags are problematic when used as filenames:
//
// ""
// ".", ".."
// anything containing '/'
//
// Replace all special character by underscores "_", an empty tag is also represented as a underscore.
func filenameFromTag(tag string) string {
switch tag {
case "", ".":
return "_"
case "..":
return "__"
}
return strings.ReplaceAll(tag, "/", "_")
}
// determine static path prefix
func staticPrefix(pathTemplate string) (prefix string) {
inVerb := false

View file

@ -273,3 +273,19 @@ func TestMakeEmptyDirs(t *testing.T) {
verifyEntries(t, expNames, expLatest, sds.entries)
}
func TestFilenameFromTag(t *testing.T) {
for _, c := range []struct {
tag, filename string
}{
{"", "_"},
{".", "_"},
{"..", "__"},
{"%.", "%."},
{"foo", "foo"},
{"foo ", "foo "},
{"foo/bar_baz", "foo_bar_baz"},
} {
test.Equals(t, c.filename, filenameFromTag(c.tag))
}
}