From c02a5184a23e9e389e7c89709b9ca1ec931dd800 Mon Sep 17 00:00:00 2001 From: Michael Kelly Date: Fri, 29 Nov 2024 23:04:20 -0800 Subject: [PATCH] Fix name collision with tar2files command If two files have the same name but are found in different subdirectories then tar2files will fail. An example of this is found in abseil-cpp where there are multiple headers with the same name, but sometimes in different subdirectories of `/usr/include`. This change tweaks our tarfile handling so as to key our lookup map based on the path minus anything before the expected prefix (this will remove the `bazel-out/...` bits from the paths generated by the tar2files rule. This provides enough context to avoid the name collisions but is still able to deal with the correct path lookup. --- pkg/rpm/tar.go | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/pkg/rpm/tar.go b/pkg/rpm/tar.go index d6aca482..f73f6925 100644 --- a/pkg/rpm/tar.go +++ b/pkg/rpm/tar.go @@ -66,8 +66,13 @@ func PrefixFilter(prefix string, reader *tar.Reader, files []string) error { fileMap := map[string]string{} for _, file := range files { - fileMap[filepath.Base(file)] = file + prefixIdx := strings.Index(file, prefix) + if prefixIdx == -1 { + return fmt.Errorf("prefix %s is not found in %s", prefix, file) + } + fileMap[file[prefixIdx:]] = file } + for { entry, err := reader.Next() if err == io.EOF { @@ -82,13 +87,14 @@ func PrefixFilter(prefix string, reader *tar.Reader, files []string) error { } else { continue } - basename := filepath.Base(name) - if _, exists := fileMap[basename]; !exists { + + if _, exists := fileMap[name]; !exists { continue } + if entry.Typeflag == tar.TypeReg { err := func() error { - writer, err := os.Create(fileMap[basename]) + writer, err := os.Create(fileMap[name]) if err != nil { return err } @@ -101,16 +107,16 @@ func PrefixFilter(prefix string, reader *tar.Reader, files []string) error { if err != nil { return err } - delete(fileMap, basename) + delete(fileMap, name) } else if entry.Typeflag == tar.TypeSymlink { linkname := strings.TrimPrefix(entry.Linkname, ".") - err = os.Symlink(linkname, fileMap[basename]) + err = os.Symlink(linkname, fileMap[name]) if err != nil { return err } - delete(fileMap, basename) + delete(fileMap, name) } else { - return fmt.Errorf("can't extract %s, only symlinks and files can be specified", fileMap[basename]) + return fmt.Errorf("can't extract %s, only symlinks and files can be specified", fileMap[name]) } }