1
0
Fork 0
mirror of https://github.com/vbatts/go-mtree.git synced 2025-10-04 04:31:00 +00:00

compare: properly compare tar_time and time

In certain circumstances, if a manifest with "time" keywords was
compared to another manifest with "tar_time" keywords, differences were
not actually reported despite there being logic for it.

Unfortunately, even though commit 26ff922da6 ("compare: implement
mtree.DirectoryHierarchy comparisons") explicitly included logic to
handle the necessary "time" -> "tar_time" conversions, the same commit
also made it so that Compare() could be instructed to only consider a
subset of keywords and failed to take into account said "time" ->
"tar_time" remapping.

Most users have likely not noticed this because gomtree will re-use the
keywords from a manifest when doing a straightforward "gomtree validate"
invocation, but if you explicitly requested "time" when validating a
"tar_time" manifest (and *not* the other way around) then any time
changes would be undetected.

Fixes: 26ff922da6 ("compare: implement mtree.DirectoryHierarchy comparisons")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
This commit is contained in:
Aleksa Sarai 2025-09-09 17:31:57 +10:00
parent b3097c1af5
commit 0beb885cbf
No known key found for this signature in database
GPG key ID: 2897FAD2B7E9446F
2 changed files with 74 additions and 8 deletions

View file

@ -3,6 +3,7 @@ package mtree
import (
"encoding/json"
"fmt"
"slices"
"strconv"
)
@ -405,15 +406,16 @@ func compare(oldDh, newDh *DirectoryHierarchy, keys []Keyword, same bool) ([]Ino
return nil, fmt.Errorf("comparison failed %s: %s", path, err)
}
// Now remove "changed" entries that don't match the keys.
// Ignore changes to keys not in the requested set.
if keys != nil {
var filterChanged []KeyDelta
for _, keyDiff := range changed {
if InKeywordSlice(keyDiff.name.Prefix(), keys) {
filterChanged = append(filterChanged, keyDiff)
}
}
changed = filterChanged
changed = slices.DeleteFunc(changed, func(delta KeyDelta) bool {
name := delta.name.Prefix()
return !InKeywordSlice(name, keys) &&
// We remap time to tar_time in compareEntry, so we
// need to treat them equivalently here.
!(name == "time" && InKeywordSlice("tar_time", keys)) &&
!(name == "tar_time" && InKeywordSlice("time", keys))
})
}
// Check if there were any actual changes.