From 1161bec19780ac4eb9376ff1e97b4f31792c0934 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 1b399973..e6d69336 100644 --- a/internal/deb/extract.go +++ b/internal/deb/extract.go @@ -246,6 +246,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) @@ -259,6 +260,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 dc97203d..d6ec277e 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) {