diff --git a/Makefile b/Makefile index 3be14965c..2fe6ec39a 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ LINTERS := FIXERS := GOLANGCI_LINT_CONFIG := $(LINT_ROOT)/.golangci.yml -GOLANGCI_LINT_VERSION ?= v2.1.6 +GOLANGCI_LINT_VERSION ?= v2.6.0 GOLANGCI_LINT_BIN := $(LINT_ROOT)/out/linters/golangci-lint-$(GOLANGCI_LINT_VERSION)-$(LINT_ARCH) $(GOLANGCI_LINT_BIN): mkdir -p $(LINT_ROOT)/out/linters diff --git a/pkg/action/diff.go b/pkg/action/diff.go index 10abd3db9..5be093332 100644 --- a/pkg/action/diff.go +++ b/pkg/action/diff.go @@ -230,7 +230,7 @@ func Diff(ctx context.Context, c malcontent.Config, _ *clog.Logger) (*malcontent srcCh, destCh := make(chan ScanResult, 1), make(chan ScanResult, 1) - srcIsArchive, destIsArchive := programkind.IsSupportedArchive(srcPath), programkind.IsSupportedArchive(destPath) + srcIsArchive, destIsArchive := programkind.IsSupportedArchive(ctx, srcPath), programkind.IsSupportedArchive(ctx, destPath) g.Go(func() error { files, base, err := relFileReport(ctx, c, srcPath, isImage) diff --git a/pkg/action/scan.go b/pkg/action/scan.go index 990d370f4..551d6c7ce 100644 --- a/pkg/action/scan.go +++ b/pkg/action/scan.go @@ -126,7 +126,7 @@ func scanSinglePath(ctx context.Context, c malcontent.Config, path string, ruleF } mime := "" - kind, err := programkind.File(path) + kind, err := programkind.File(ctx, path) if err != nil && !interactive(c) { logger.Errorf("file type failure: %s: %s", path, err) } @@ -523,7 +523,7 @@ func processPath(ctx context.Context, path string, scanInfo scanPathInfo, c malc case <-ctx.Done(): return ctx.Err() default: - if programkind.IsSupportedArchive(path) { + if programkind.IsSupportedArchive(ctx, path) { return handleArchiveFile(ctx, path, c, r, matchChan, matchOnce, logger) } return handleSingleFile(ctx, path, scanInfo, c, r, matchChan, matchOnce, logger) diff --git a/pkg/archive/archive.go b/pkg/archive/archive.go index a9a9054c8..e16bc2302 100644 --- a/pkg/archive/archive.go +++ b/pkg/archive/archive.go @@ -57,7 +57,7 @@ func extractNestedArchive(ctx context.Context, c malcontent.Config, d string, f } isArchive := false - ft, err := programkind.File(fullPath) + ft, err := programkind.File(ctx, fullPath) if err != nil { return fmt.Errorf("failed to determine file type: %w", err) } @@ -156,7 +156,7 @@ func ExtractArchiveToTempDir(ctx context.Context, c malcontent.Config, path stri var extract func(context.Context, string, string) error // Check for zlib-compressed files first and use the zlib-specific function - ft, err := programkind.File(path) + ft, err := programkind.File(ctx, path) if err != nil { return "", fmt.Errorf("failed to determine file type: %w", err) } diff --git a/pkg/archive/gzip.go b/pkg/archive/gzip.go index 5de1e648d..78d6b2b7c 100644 --- a/pkg/archive/gzip.go +++ b/pkg/archive/gzip.go @@ -31,7 +31,7 @@ func ExtractGzip(ctx context.Context, d string, f string) error { // Check whether the provided file is a valid gzip archive var isGzip bool - if ft, err := programkind.File(f); err == nil && ft != nil { + if ft, err := programkind.File(ctx, f); err == nil && ft != nil { if _, ok := GzMIME[ft.MIME]; ok { isGzip = true } diff --git a/pkg/archive/tar.go b/pkg/archive/tar.go index d3299612e..f166f0306 100644 --- a/pkg/archive/tar.go +++ b/pkg/archive/tar.go @@ -63,7 +63,7 @@ func ExtractTar(ctx context.Context, d string, f string) error { isTGZ := strings.Contains(f, ".tar.gz") || strings.Contains(f, ".tgz") var isGzip bool - if ft, err := programkind.File(f); err == nil && ft != nil { + if ft, err := programkind.File(ctx, f); err == nil && ft != nil { if _, ok := GzMIME[ft.MIME]; ok { isGzip = true } diff --git a/pkg/archive/upx.go b/pkg/archive/upx.go index e33ded4c3..43c59e1de 100644 --- a/pkg/archive/upx.go +++ b/pkg/archive/upx.go @@ -52,7 +52,7 @@ func ExtractUPX(ctx context.Context, d, f string) error { return fmt.Errorf("failed to write file: %w", err) } - cmd := exec.Command("upx", "-d", "-k", target) + cmd := exec.CommandContext(ctx, "upx", "-d", "-k", target) output, err := cmd.CombinedOutput() if err != nil { os.Remove(target) diff --git a/pkg/archive/zip.go b/pkg/archive/zip.go index e2ec9cfce..a13f30f16 100644 --- a/pkg/archive/zip.go +++ b/pkg/archive/zip.go @@ -52,7 +52,7 @@ func ExtractZip(ctx context.Context, d string, f string) error { } var isZip bool - if ft, err := programkind.File(f); err == nil && ft != nil { + if ft, err := programkind.File(ctx, f); err == nil && ft != nil { if _, ok := zipMIME[ft.MIME]; ok { isZip = true } diff --git a/pkg/programkind/programkind.go b/pkg/programkind/programkind.go index c722a159d..6ada6e93f 100644 --- a/pkg/programkind/programkind.go +++ b/pkg/programkind/programkind.go @@ -5,6 +5,7 @@ package programkind import ( "bytes" + "context" "errors" "fmt" "io/fs" @@ -123,11 +124,11 @@ const headerSize int = 512 // IsSupportedArchive returns whether a path can be processed by our archive extractor. // UPX files are an edge case since they may or may not even have an extension that can be referenced. -func IsSupportedArchive(path string) bool { +func IsSupportedArchive(ctx context.Context, path string) bool { if _, isValidArchive := ArchiveMap[GetExt(path)]; isValidArchive { return true } - if ft, err := File(path); err == nil && ft != nil { + if ft, err := File(ctx, path); err == nil && ft != nil { if ft.MIME == "application/x-upx" { return true } @@ -179,7 +180,7 @@ func UPXInstalled() error { } // IsValidUPX checks whether a suspected UPX-compressed file can be decompressed with UPX. -func IsValidUPX(header []byte, path string) (bool, error) { +func IsValidUPX(ctx context.Context, header []byte, path string) (bool, error) { if !bytes.Contains(header, []byte("UPX!")) { return false, nil } @@ -188,7 +189,7 @@ func IsValidUPX(header []byte, path string) (bool, error) { return false, err } - cmd := exec.Command("upx", "-l", "-f", path) + cmd := exec.CommandContext(ctx, "upx", "-l", "-f", path) output, err := cmd.CombinedOutput() if err != nil && (bytes.Contains(output, []byte("NotPackedException")) || @@ -240,7 +241,7 @@ func makeFileType(path string, ext string, mime string) *FileType { } // File detects what kind of program this file might be. -func File(path string) (*FileType, error) { +func File(ctx context.Context, path string) (*FileType, error) { // Follow symlinks and return cleanly if the target does not exist _, err := filepath.EvalSymlinks(path) if os.IsNotExist(err) { @@ -292,7 +293,7 @@ func File(path string) (*FileType, error) { } // final strategy: DIY matching where mimetype is too strict. - if isUPX, err := IsValidUPX(hdr, path); err == nil && isUPX { + if isUPX, err := IsValidUPX(ctx, hdr, path); err == nil && isUPX { return Path(".upx"), nil } diff --git a/pkg/programkind/programkind_test.go b/pkg/programkind/programkind_test.go index 1fed5a319..287478331 100644 --- a/pkg/programkind/programkind_test.go +++ b/pkg/programkind/programkind_test.go @@ -27,7 +27,7 @@ func TestFile(t *testing.T) { for _, tt := range tests { t.Run(tt.in, func(t *testing.T) { t.Parallel() - got, err := File(filepath.Join("testdata/", tt.in)) + got, err := File(t.Context(), filepath.Join("testdata/", tt.in)) if err != nil { t.Errorf("File(%s) returned error: %v", tt.in, err) }