@@ -2,11 +2,12 @@ package vex
2
2
3
3
import (
4
4
"bytes"
5
- "fmt "
5
+ "context "
6
6
"io"
7
7
"net/http"
8
8
"net/url"
9
9
10
+ "github.com/samber/lo"
10
11
"golang.org/x/xerrors"
11
12
12
13
"github.com/aquasecurity/trivy/pkg/fanal/artifact"
@@ -20,15 +21,17 @@ type SBOMReferenceSet struct {
20
21
}
21
22
22
23
func NewSBOMReferenceSet (report * types.Report ) (* SBOMReferenceSet , error ) {
23
-
24
24
if report .ArtifactType != artifact .TypeCycloneDX {
25
25
return nil , xerrors .Errorf ("externalReferences can only be used when scanning CycloneDX SBOMs: %w" , report .ArtifactType )
26
26
}
27
27
28
- var externalRefs = report .BOM .ExternalReferences ()
28
+ ctx := log .WithContextPrefix (context .Background (), "vex" )
29
+ ctx = log .WithContextAttrs (ctx , log .String ("type" , "sbom_reference" ))
30
+
31
+ externalRefs := report .BOM .ExternalReferences ()
29
32
urls := parseToURLs (externalRefs )
30
33
31
- v , err := retrieveExternalVEXDocuments (urls , report )
34
+ v , err := retrieveExternalVEXDocuments (ctx , urls , report )
32
35
if err != nil {
33
36
return nil , xerrors .Errorf ("failed to fetch external VEX documents: %w" , err )
34
37
} else if v == nil {
@@ -38,48 +41,41 @@ func NewSBOMReferenceSet(report *types.Report) (*SBOMReferenceSet, error) {
38
41
return & SBOMReferenceSet {VEXes : v }, nil
39
42
}
40
43
41
- func parseToURLs (refs []core.ExternalReference ) []url.URL {
42
- var urls []url.URL
43
- for _ , ref := range refs {
44
- if ref .Type == core .ExternalReferenceVEX {
45
- val , err := url .Parse (ref .URL )
44
+ func parseToURLs (refs []core.ExternalReference ) []* url.URL {
45
+ return lo .FilterMap (refs , func (ref core.ExternalReference , _ int ) (* url.URL , bool ) {
46
+ if ref .Type != core .ExternalReferenceVEX {
47
+ return nil , false
48
+ }
49
+ val , err := url .Parse (ref .URL )
50
+ if err != nil || (val .Scheme != "https" && val .Scheme != "http" ) {
46
51
// do not concern ourselves with relative URLs at this point
47
- if err != nil || (val .Scheme != "https" && val .Scheme != "http" ) {
48
- continue
49
- }
50
- urls = append (urls , * val )
52
+ return nil , false
51
53
}
52
- }
53
- return urls
54
+ return val , true
55
+ })
54
56
}
55
57
56
- func retrieveExternalVEXDocuments (refs []url.URL , report * types.Report ) ([]VEX , error ) {
57
-
58
- logger := log .WithPrefix ("vex" ).With (log .String ("type" , "external_reference" ))
59
-
58
+ func retrieveExternalVEXDocuments (ctx context.Context , refs []* url.URL , report * types.Report ) ([]VEX , error ) {
60
59
var docs []VEX
61
60
for _ , ref := range refs {
62
- doc , err := retrieveExternalVEXDocument (ref , report )
61
+ doc , err := retrieveExternalVEXDocument (ctx , ref , report )
63
62
if err != nil {
64
63
return nil , xerrors .Errorf ("failed to retrieve external VEX document: %w" , err )
65
64
}
66
65
docs = append (docs , doc )
67
66
}
68
- logger . Debug ( "Retrieved external VEX documents" , "count" , len (docs ))
67
+ log . DebugContext ( ctx , "Retrieved external VEX documents" , log . Int ( "count" , len (docs ) ))
69
68
70
69
if len (docs ) == 0 {
71
- logger . Info ( "No external VEX documents found" )
70
+ log . DebugContext ( ctx , "No external VEX documents found" )
72
71
return nil , nil
73
72
}
74
73
return docs , nil
75
74
76
75
}
77
76
78
- func retrieveExternalVEXDocument (vexUrl url.URL , report * types.Report ) (VEX , error ) {
79
-
80
- logger := log .WithPrefix ("vex" ).With (log .String ("type" , "external_reference" ))
81
-
82
- logger .Info (fmt .Sprintf ("Retrieving external VEX document from host %s" , vexUrl .Host ))
77
+ func retrieveExternalVEXDocument (ctx context.Context , vexUrl * url.URL , report * types.Report ) (VEX , error ) {
78
+ log .DebugContext (ctx , "Retrieving external VEX document" , log .String ("url" , vexUrl .String ()))
83
79
84
80
res , err := http .Get (vexUrl .String ())
85
81
if err != nil {
@@ -96,15 +92,14 @@ func retrieveExternalVEXDocument(vexUrl url.URL, report *types.Report) (VEX, err
96
92
return nil , xerrors .Errorf ("unable to read response into memory: %w" , err )
97
93
}
98
94
99
- if v , err := decodeVEX (bytes .NewReader (val ), vexUrl .String (), report ); err != nil {
95
+ v , err := decodeVEX (bytes .NewReader (val ), vexUrl .String (), report )
96
+ if err != nil {
100
97
return nil , xerrors .Errorf ("unable to load VEX from external reference: %w" , err )
101
- } else {
102
- return v , nil
103
98
}
99
+ return v , nil
104
100
}
105
101
106
102
func (set * SBOMReferenceSet ) NotAffected (vuln types.DetectedVulnerability , product , subComponent * core.Component ) (types.ModifiedFinding , bool ) {
107
-
108
103
for _ , vex := range set .VEXes {
109
104
if m , notAffected := vex .NotAffected (vuln , product , subComponent ); notAffected {
110
105
return m , notAffected
0 commit comments