mirror of
https://github.com/anchore/syft.git
synced 2026-10-30 14:02:26 +01:00
fix: only skip META-INF/maven poms inside an extracted java archive
`isArchiveMetaPom` was an unconditional `strings.Contains(path, "META-INF/maven/")`, so the pom cataloger dropped real poms everywhere, even with the feature off: exploded wars (`WEB-INF/classes/META-INF/maven/...`), test fixtures under `src/test/resources`, source tarballs. That's a regression on the default path. the skip exists because inside a jar those poms are raw build copies that java already covers from `pom.properties`. So it now applies only when the traversal on the context is a java archive. Outside one, or inside a tarball java doesn't describe, the poms are cataloged as before this PR. Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/internal/archive"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/internal/unknown"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
@@ -40,7 +41,7 @@ func (p pomXMLCataloger) Catalog(ctx context.Context, fileResolver file.Resolver
|
||||
var poms []*maven.Project
|
||||
pomLocations := map[*maven.Project]file.Location{}
|
||||
for _, pomLocation := range locations {
|
||||
if isArchiveMetaPom(pomLocation) {
|
||||
if isArchiveMetaPom(ctx, pomLocation) {
|
||||
continue
|
||||
}
|
||||
pom, err := readPomFromLocation(fileResolver, pomLocation)
|
||||
@@ -307,7 +308,14 @@ func pomParent(ctx context.Context, r *maven.Resolver, pom *maven.Project) *pkg.
|
||||
// unresolved ${property} references and versions inherited from parent POMs absent from the archive.
|
||||
// The java-archive-cataloger identifies these archives from pom.properties, whose values are always
|
||||
// resolved, so skipping them here avoids phantom dependency packages.
|
||||
func isArchiveMetaPom(location file.Location) bool {
|
||||
//
|
||||
// This only holds inside an extracted java archive. Anywhere else (an exploded war, test fixtures under
|
||||
// src/test/resources, a tarball of a source tree) nothing else reads these poms, so they are cataloged.
|
||||
func isArchiveMetaPom(ctx context.Context, location file.Location) bool {
|
||||
trav := archive.TraversalFromContext(ctx)
|
||||
if trav == nil || !isJavaArchiveName(trav.Location.Path()) {
|
||||
return false
|
||||
}
|
||||
return strings.Contains(location.Path(), "META-INF/maven/")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package java
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/internal/archive"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/cataloging"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
@@ -726,9 +728,21 @@ func Test_isArchiveMetaPom(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
loc := file.NewLocation(test.path)
|
||||
assert.Equal(t, test.expected, isArchiveMetaPom(loc))
|
||||
assert.Equal(t, test.expected, isArchiveMetaPom(insideJar(t), loc))
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("only inside an extracted java archive", func(t *testing.T) {
|
||||
loc := file.NewLocation("WEB-INF/classes/META-INF/maven/com.example/my-lib/pom.xml")
|
||||
assert.False(t, isArchiveMetaPom(context.Background(), loc), "outside any archive, e.g. an exploded war")
|
||||
inTarball := archive.WithTraversal(context.Background(), &archive.Traversal{Location: file.NewLocation("/src.tar.gz")})
|
||||
assert.False(t, isArchiveMetaPom(inTarball, loc), "inside an archive java does not describe")
|
||||
})
|
||||
}
|
||||
|
||||
// insideJar is a context as the archive cataloger task sets it up while cataloging a jar's contents.
|
||||
func insideJar(t *testing.T) context.Context {
|
||||
return archive.WithTraversal(pkgtest.Context(t), &archive.Traversal{Location: file.NewLocation("/app.jar")})
|
||||
}
|
||||
|
||||
func Test_pomCatalogerSkipsMetaInfPoms(t *testing.T) {
|
||||
@@ -743,8 +757,17 @@ func Test_pomCatalogerSkipsMetaInfPoms(t *testing.T) {
|
||||
|
||||
pkgtest.NewCatalogTester().
|
||||
FromDirectory(t, "testdata/pom/meta-inf-archive").
|
||||
WithContext(insideJar(t)).
|
||||
Expects(nil, nil).
|
||||
TestCataloger(t, cat)
|
||||
|
||||
// the same pom outside a jar is a project file like any other
|
||||
pkgtest.NewCatalogTester().
|
||||
FromDirectory(t, "testdata/pom/meta-inf-archive").
|
||||
ExpectsAssertion(func(t *testing.T, pkgs []pkg.Package, _ []artifact.Relationship) {
|
||||
assert.NotEmpty(t, pkgs)
|
||||
}).
|
||||
TestCataloger(t, cat)
|
||||
}
|
||||
|
||||
func Test_pomCatalogerSkipsMetaInfButKeepsProjectPom(t *testing.T) {
|
||||
@@ -803,7 +826,11 @@ func Test_pomCatalogerSkipsMetaInfButKeepsProjectPom(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
pkgtest.TestCataloger(t, "testdata/pom/mixed-meta-inf-and-project", cat, expectedPkgs, expectedRelationships)
|
||||
pkgtest.NewCatalogTester().
|
||||
FromDirectory(t, "testdata/pom/mixed-meta-inf-and-project").
|
||||
WithContext(insideJar(t)).
|
||||
Expects(expectedPkgs, expectedRelationships).
|
||||
TestCataloger(t, cat)
|
||||
}
|
||||
|
||||
func expectedTransientPackageData() expected {
|
||||
|
||||
Reference in New Issue
Block a user