From cb84caae5ec7a8c32e7102287c1b4be09e72e000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Virtus?= Date: Thu, 15 Jun 2023 11:17:53 +0200 Subject: [PATCH] extract: Proper modes with multiple copies We use the source tar entry header to compute fs.FileMode. When the target path has a different mode, we modify the source header first. Consequently, when a source path is mapped to multiple target paths, and when one target path overrides the mode and the following one doesn't, the following one will have the first one's mode. Fix it by remembering the source header mode. --- internal/deb/extract.go | 2 ++ internal/deb/extract_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/internal/deb/extract.go b/internal/deb/extract.go index 3b837bb5..98dba0b3 100644 --- a/internal/deb/extract.go +++ b/internal/deb/extract.go @@ -245,6 +245,7 @@ func extractData(dataReader io.Reader, options *ExtractOptions) error { } var pathReader io.Reader = tarReader + origMode := tarHeader.Mode for _, extractInfo := range extractInfos { if contentIsCached { pathReader = bytes.NewReader(contentCache) @@ -258,6 +259,7 @@ func extractData(dataReader io.Reader, options *ExtractOptions) error { if err := createParents(targetPath); err != nil { return err } + tarHeader.Mode = origMode if extractInfo.Mode != 0 { tarHeader.Mode = int64(extractInfo.Mode) } diff --git a/internal/deb/extract_test.go b/internal/deb/extract_test.go index 04b48344..47411bda 100644 --- a/internal/deb/extract_test.go +++ b/internal/deb/extract_test.go @@ -413,6 +413,32 @@ var extractTests = []extractTest{{ "/a/b/c/": "dir 0706", "/a/b/c/d": "file 0601 empty", }, +}, { + summary: "Copies with different permissions", + pkgdata: testutil.MustMakeDeb([]testutil.TarEntry{ + DIR(0701, "./a/"), + REG(0601, "./b", ""), + }), + options: deb.ExtractOptions{ + Extract: map[string][]deb.ExtractInfo{ + "/a/": []deb.ExtractInfo{ + {Path: "/b/"}, + {Path: "/c/", Mode: 0702}, + {Path: "/d/", Mode: 01777}, + {Path: "/e/"}, + {Path: "/f/", Mode: 0723}, + {Path: "/g/"}, + }, + }, + }, + result: map[string]string{ + "/b/": "dir 0701", + "/c/": "dir 0702", + "/d/": "dir 01777", + "/e/": "dir 0701", + "/f/": "dir 0723", + "/g/": "dir 0701", + }, }} func (s *S) TestExtract(c *C) {