diff --git a/pkg/ovalutil/dpkg.go b/pkg/ovalutil/dpkg.go index 89f7bd0e3..37d809d09 100644 --- a/pkg/ovalutil/dpkg.go +++ b/pkg/ovalutil/dpkg.go @@ -64,6 +64,11 @@ func DpkgDefsToVulns(ctx context.Context, root *oval.Root, protoVulns ProtoVulns // // thus we *should* only need to care about a single dpkginfo_object and optionally a state object providing the package's fixed-in version. + if len(objRefs) == 0 { + stats.Obj++ + continue + } + objRef := objRefs[0].ObjectRef object, err := dpkgObjectLookup(root, objRef) switch { diff --git a/pkg/ovalutil/objectref_test.go b/pkg/ovalutil/objectref_test.go new file mode 100644 index 000000000..c28968706 --- /dev/null +++ b/pkg/ovalutil/objectref_test.go @@ -0,0 +1,61 @@ +package ovalutil + +import ( + "context" + "encoding/xml" + "fmt" + "testing" + + "github.com/quay/claircore" + "github.com/quay/goval-parser/oval" +) + +// A test element is only required to carry an object reference; a feed that +// omits it still parses. +const missingObjectRef = ` + + + example + + + + + + + <%s id="oval:com.example:tst:1" check="at least one" comment="package is installed"/> + +` + +func protoVuln(oval.Definition) ([]*claircore.Vulnerability, error) { + return []*claircore.Vulnerability{{Name: "example"}}, nil +} + +func TestDefsToVulnsWithoutObjectRef(t *testing.T) { + for _, kind := range []string{"rpminfo_test", "dpkginfo_test"} { + t.Run(kind, func(t *testing.T) { + root := &oval.Root{} + if err := xml.Unmarshal([]byte(fmt.Sprintf(missingObjectRef, kind)), root); err != nil { + t.Fatalf("parsing the oval document: %v", err) + } + + var ( + vulns []*claircore.Vulnerability + err error + ) + switch kind { + case "rpminfo_test": + vulns, err = RPMDefsToVulns(context.Background(), root, protoVuln) + case "dpkginfo_test": + vulns, err = DpkgDefsToVulns(context.Background(), root, protoVuln, func(_ oval.Definition, name *oval.DpkgName) []string { + return []string{name.Body} + }) + } + if err != nil { + t.Fatalf("got an error: %v", err) + } + if len(vulns) != 0 { + t.Errorf("expected the criterion to be skipped, got %d vulnerabilities", len(vulns)) + } + }) + } +} diff --git a/pkg/ovalutil/rpm.go b/pkg/ovalutil/rpm.go index df876f79b..99ac4c426 100644 --- a/pkg/ovalutil/rpm.go +++ b/pkg/ovalutil/rpm.go @@ -89,6 +89,11 @@ func RPMDefsToVulns(ctx context.Context, root *oval.Root, protoVulns ProtoVulnsF // // thus we *should* only need to care about a single rpminfo_object and optionally a state object providing the package's fixed-in version. + if len(objRefs) == 0 { + slog.DebugContext(ctx, "test has no object reference, moving to next criterion", "test_ref", criterion.TestRef) + continue + } + objRef := objRefs[0].ObjectRef object, err := rpmObjectLookup(root, objRef) switch {