From 63dc31a80a5fb4a0ecee4b75a1b34baa585acea0 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Sun, 4 Jun 2023 20:00:33 +1000 Subject: [PATCH 1/2] parse: do not allow FullType entries to affect the current directory As per the spec[1], Full entries must not affect the current directory. Handling this incorrectly caused us issues with certain manifests (ones with mixed Relative and Full entries, which is something casync does by accident). This is a partial fix for the issues with verifying casync-mtree's output but there are a few other issues to iron out (including one within casync). [1]: https://man.netbsd.org/mtree.5 Signed-off-by: Aleksa Sarai --- parse.go | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/parse.go b/parse.go index 36a7163..9094508 100644 --- a/parse.go +++ b/parse.go @@ -72,27 +72,30 @@ func ParseSpec(r io.Reader) (*DirectoryHierarchy, error) { break } } + // parse the options f := strings.Fields(str) e.Name = filepath.Clean(f[0]) + e.Keywords = StringToKeyVals(f[1:]) + // TODO: gather keywords if using tar stream + var isDir bool + for _, kv := range e.Keywords { + if kv.Keyword() == "type" { + isDir = kv.Value() == "dir" + } + } if strings.Contains(e.Name, "/") { e.Type = FullType } else { e.Type = RelativeType - } - e.Keywords = StringToKeyVals(f[1:]) - // TODO: gather keywords if using tar stream - e.Parent = creator.curDir - for i := range e.Keywords { - kv := KeyVal(e.Keywords[i]) - if kv.Keyword() == "type" { - if kv.Value() == "dir" { - creator.curDir = &e - } else { - creator.curEnt = &e - } + e.Parent = creator.curDir + if isDir { + creator.curDir = &e } } + if !isDir { + creator.curEnt = &e + } e.Set = creator.curSet default: // TODO(vbatts) log a warning? From 07c8c8e17ae72742b2034a39c2281518ef27a224 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Sun, 4 Jun 2023 20:02:40 +1000 Subject: [PATCH 2/2] parse: clean path after checking if entry is a FullType The spec[1] doesn't mention anything about cleaning paths, but it does explicitly refer to the path containing a "/". Cleaning the path before checking if the entry is a FullType would result in the simplest way of forcing directories to be FullTypes (appending a "/" to the pathname of any directory) not working with go-mtree. [1]: https://man.netbsd.org/mtree.5 Signed-off-by: Aleksa Sarai --- parse.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/parse.go b/parse.go index 9094508..e385eaf 100644 --- a/parse.go +++ b/parse.go @@ -75,7 +75,7 @@ func ParseSpec(r io.Reader) (*DirectoryHierarchy, error) { // parse the options f := strings.Fields(str) - e.Name = filepath.Clean(f[0]) + e.Name = f[0] e.Keywords = StringToKeyVals(f[1:]) // TODO: gather keywords if using tar stream var isDir bool @@ -97,6 +97,10 @@ func ParseSpec(r io.Reader) (*DirectoryHierarchy, error) { creator.curEnt = &e } e.Set = creator.curSet + // we need to clean the filepath at the end because '/'s can be + // stripped, which would cause FullTypes to be treated as + // RelativeTypes above + e.Name = filepath.Clean(e.Name) default: // TODO(vbatts) log a warning? continue