From 1b6778039fb7b68f226b00674564fd03d82535c2 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 7de591ab..e86b4553 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) {