package release import ( "github.com/carlosframework/platform/internal/rootstate" "os" "path/filepath" "strings" ) func GenerationFileProof(path string, before, after rootstate.FileIdentity) bool { if before.Same(after) { return true } source := func(id rootstate.FileIdentity) (string, bool) { root, e1 := generationProofUnescape(id.MountRoot) point, e2 := generationProofUnescape(id.MountPoint) if e1 != nil || e2 != nil || !filepath.IsAbs(root) || !filepath.IsAbs(point) || filepath.Clean(root) != root || filepath.Clean(point) != point { return "", false } rel, err := filepath.Rel(point, path) if err != nil || !filepath.IsLocal(rel) { return "", false } return filepath.Join(root, rel), true } if before.SameMountNamespace(after) || before.MountLineage == "" || after.MountLineage == "" || before.MountLineage == after.MountLineage || !strings.HasSuffix(before.MountLineage, "\n"+after.MountLineage) { return false } beforePoint, e1 := generationProofUnescape(before.MountPoint) afterPoint, e2 := generationProofUnescape(after.MountPoint) rel, err := filepath.Rel(afterPoint, beforePoint) if e1 != nil || e2 != nil || err != nil || rel == "." || !filepath.IsLocal(rel) { return false } a, ok1 := source(before) b, ok2 := source(after) if !ok1 || !ok2 || a != b { return false } after.MountRoot, after.MountPoint, after.MountLineage = before.MountRoot, before.MountPoint, before.MountLineage return before.Same(after) } func generationProofUnescape(s string) (string, error) { var out strings.Builder for i := 0; i < len(s); i++ { if s[i] != '\\' { out.WriteByte(s[i]) continue } if i+3 >= len(s) { return "", os.ErrPermission } switch s[i : i+4] { case "\\040": out.WriteByte(' ') case "\\011": out.WriteByte('\t') case "\\012": out.WriteByte('\n') case "\\134": out.WriteByte('\\') default: return "", os.ErrPermission } i += 3 } return out.String(), nil }