mirror of
https://github.com/anchore/syft.git
synced 2026-02-12 10:36:45 +01:00
fix: duplicate file in tar archive causes read to fail (#1445)
This commit is contained in:
parent
e480443c8c
commit
725529f43f
@ -301,6 +301,12 @@ func fileAnalysisPath(path string) (string, func()) {
|
|||||||
// unarchived.
|
// unarchived.
|
||||||
envelopedUnarchiver, err := archiver.ByExtension(path)
|
envelopedUnarchiver, err := archiver.ByExtension(path)
|
||||||
if unarchiver, ok := envelopedUnarchiver.(archiver.Unarchiver); err == nil && ok {
|
if unarchiver, ok := envelopedUnarchiver.(archiver.Unarchiver); err == nil && ok {
|
||||||
|
if tar, ok := unarchiver.(*archiver.Tar); ok {
|
||||||
|
// when tar files are extracted, if there are multiple entries at the same
|
||||||
|
// location, the last entry wins
|
||||||
|
// NOTE: this currently does not display any messages if an overwrite happens
|
||||||
|
tar.OverwriteExisting = true
|
||||||
|
}
|
||||||
unarchivedPath, tmpCleanup, err := unarchiveToTmp(path, unarchiver)
|
unarchivedPath, tmpCleanup, err := unarchiveToTmp(path, unarchiver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("file could not be unarchived: %+v", err)
|
log.Warnf("file could not be unarchived: %+v", err)
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
package source
|
package source
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -252,6 +253,8 @@ func TestNewFromFile_WithArchive(t *testing.T) {
|
|||||||
expString string
|
expString string
|
||||||
inputPaths []string
|
inputPaths []string
|
||||||
expRefs int
|
expRefs int
|
||||||
|
layer2 bool
|
||||||
|
contents string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "path detected",
|
desc: "path detected",
|
||||||
@ -259,10 +262,18 @@ func TestNewFromFile_WithArchive(t *testing.T) {
|
|||||||
inputPaths: []string{"/.vimrc"},
|
inputPaths: []string{"/.vimrc"},
|
||||||
expRefs: 1,
|
expRefs: 1,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "lest entry for duplicate paths",
|
||||||
|
input: "test-fixtures/path-detected",
|
||||||
|
inputPaths: []string{"/.vimrc"},
|
||||||
|
expRefs: 1,
|
||||||
|
layer2: true,
|
||||||
|
contents: "Another .vimrc file",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
archivePath := setupArchiveTest(t, test.input)
|
archivePath := setupArchiveTest(t, test.input, test.layer2)
|
||||||
|
|
||||||
src, cleanup := NewFromFile(archivePath)
|
src, cleanup := NewFromFile(archivePath)
|
||||||
if cleanup != nil {
|
if cleanup != nil {
|
||||||
@ -279,6 +290,16 @@ func TestNewFromFile_WithArchive(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Len(t, refs, test.expRefs)
|
assert.Len(t, refs, test.expRefs)
|
||||||
|
|
||||||
|
if test.contents != "" {
|
||||||
|
reader, err := resolver.FileContentsByLocation(refs[0])
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
data, err := io.ReadAll(reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, test.contents, string(data))
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -716,7 +737,7 @@ func Test_crossPlatformExclusions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createArchive creates a new archive file at destinationArchivePath based on the directory found at sourceDirPath.
|
// createArchive creates a new archive file at destinationArchivePath based on the directory found at sourceDirPath.
|
||||||
func createArchive(t testing.TB, sourceDirPath, destinationArchivePath string) {
|
func createArchive(t testing.TB, sourceDirPath, destinationArchivePath string, layer2 bool) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
cwd, err := os.Getwd()
|
cwd, err := os.Getwd()
|
||||||
@ -749,13 +770,21 @@ func createArchive(t testing.TB, sourceDirPath, destinationArchivePath string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if layer2 {
|
||||||
|
cmd = exec.Command("tar", "-rvf", destinationArchivePath, ".")
|
||||||
|
cmd.Dir = filepath.Join(cwd, "test-fixtures", path.Base(sourceDirPath+"-2"))
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
t.Fatalf("unable to start tar appending fixture script: %+v", err)
|
||||||
|
}
|
||||||
|
_ = cmd.Wait()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupArchiveTest encapsulates common test setup work for tar file tests. It returns a cleanup function,
|
// setupArchiveTest encapsulates common test setup work for tar file tests. It returns a cleanup function,
|
||||||
// which should be called (typically deferred) by the caller, the path of the created tar archive, and an error,
|
// which should be called (typically deferred) by the caller, the path of the created tar archive, and an error,
|
||||||
// which should trigger a fatal test failure in the consuming test. The returned cleanup function will never be nil
|
// which should trigger a fatal test failure in the consuming test. The returned cleanup function will never be nil
|
||||||
// (even if there's an error), and it should always be called.
|
// (even if there's an error), and it should always be called.
|
||||||
func setupArchiveTest(t testing.TB, sourceDirPath string) string {
|
func setupArchiveTest(t testing.TB, sourceDirPath string, layer2 bool) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
archivePrefix, err := ioutil.TempFile("", "syft-archive-TEST-")
|
archivePrefix, err := ioutil.TempFile("", "syft-archive-TEST-")
|
||||||
@ -771,7 +800,7 @@ func setupArchiveTest(t testing.TB, sourceDirPath string) string {
|
|||||||
|
|
||||||
destinationArchiveFilePath := archivePrefix.Name() + ".tar"
|
destinationArchiveFilePath := archivePrefix.Name() + ".tar"
|
||||||
t.Logf("archive path: %s", destinationArchiveFilePath)
|
t.Logf("archive path: %s", destinationArchiveFilePath)
|
||||||
createArchive(t, sourceDirPath, destinationArchiveFilePath)
|
createArchive(t, sourceDirPath, destinationArchiveFilePath, layer2)
|
||||||
|
|
||||||
t.Cleanup(
|
t.Cleanup(
|
||||||
assertNoError(t,
|
assertNoError(t,
|
||||||
|
|||||||
1
syft/source/test-fixtures/path-detected-2/.vimrc
Normal file
1
syft/source/test-fixtures/path-detected-2/.vimrc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Another .vimrc file
|
||||||
0
syft/source/test-fixtures/path-detected-2/empty
Normal file
0
syft/source/test-fixtures/path-detected-2/empty
Normal file
Loading…
x
Reference in New Issue
Block a user