Skip to content

Commit

Permalink
Add workaround for macOS archive xattrs (#2504)
Browse files Browse the repository at this point in the history
This commit introduces a workaround for an issue with .tar archives
created with libarchive on Darwin/macOS. When encountering a file that
has extended attributes, such as the com.apple.provenance attribute, it
will add a corresponding AppleDouble file with the prefix "._" in the
same directory. Because these files have the same filename otherwise,
the buf tool will see these when they correspond to proto files and
subsequently fail to parse them as protobuf IDL.

Due to the fact that libarchive is used by default with the version of
tar that ships with macOS, and the provenance extended attribute is set
by macOS under many conditions when SIP is enabled, archives with these
files are likely to occur on macOS.

.zip archives created by libarchive do not seem to have this issue.
However, .zip archives created by Archive Utility.app have a very
similar behavior when encountering extended attributes: it will place
AppleDouble files in a separate directory tree under the MACOSX
directory, but also with the "._" prefix. Since this can be handled by
the same logic, this behavior is extended to ZIP files as well.

Closes #2387.
  • Loading branch information
jchadwick-buf authored Oct 18, 2023
1 parent 7edd4f5 commit df619b4
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

## [Unreleased]

- No changes yet.
- Fix issue where `buf build` and other commands may fail when handling certain
archives created on macOS that contain files with extended attributes.

## [v1.27.1] - 2023-10-16

Expand Down
22 changes: 22 additions & 0 deletions private/pkg/storage/storagearchive/storagearchive.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"errors"
"fmt"
"io"
"io/fs"
"math"
"strings"

"github.com/bufbuild/buf/private/pkg/normalpath"
"github.com/bufbuild/buf/private/pkg/storage"
Expand Down Expand Up @@ -109,6 +111,9 @@ func Untar(
if tarHeader.Size < 0 {
return fmt.Errorf("invalid size for tar file %s: %d", tarHeader.Name, tarHeader.Size)
}
if isAppleExtendedAttributesFile(tarHeader.FileInfo()) {
continue
}
path, ok, err := unmapArchivePath(tarHeader.Name, mapper, stripComponentCount)
if err != nil {
return err
Expand Down Expand Up @@ -210,6 +215,9 @@ func Unzip(
if !ok {
continue
}
if isAppleExtendedAttributesFile(zipFile.FileInfo()) {
continue
}
if zipFile.FileInfo().Mode().IsRegular() {
if err := copyZipFile(ctx, writeBucket, zipFile, path); err != nil {
return err
Expand All @@ -219,6 +227,20 @@ func Unzip(
return nil
}

func isAppleExtendedAttributesFile(fileInfo fs.FileInfo) bool {
// On macOS, .tar archives created with libarchive will contain additional
// files with a prefix of "._" if there are files with extended attributes
// and copyfile is enabled.
// Archive Utility.app has a similar behavior when creating .zip archives,
// except they are placed under a separate MACOSX directory tree.
// Here, both are handled by just ignoring all files with a "._" prefix.
// This is a reasonable compromise because files that live in a Module
// (.proto files, configuration files such as buf.yaml, README files) are
// almost never prefixed with ._, and fixing this issue in this manner
// outweighs the slight incorrectness.
return strings.HasPrefix(fileInfo.Name(), "._")
}

func copyZipFile(
ctx context.Context,
writeBucket storage.WriteBucket,
Expand Down

0 comments on commit df619b4

Please sign in to comment.