diff --git a/vulnfeeds/cmd/combine-to-osv/main.go b/vulnfeeds/cmd/combine-to-osv/main.go index 8992181c5bd..231e82b96ca 100644 --- a/vulnfeeds/cmd/combine-to-osv/main.go +++ b/vulnfeeds/cmd/combine-to-osv/main.go @@ -614,12 +614,41 @@ func getExtractedEvents(r *osvschema.Range) []*structpb.Value { return val.GetListValue().GetValues() } -func parseExtractedEvent(v *structpb.Value) ExtractedEvent { +func parseExtractedEvent(v *structpb.Value) []ExtractedEvent { s := v.GetStructValue() if s == nil { - return ExtractedEvent{} + return nil } fields := s.GetFields() + + if rangeVal, ok := fields["range"]; ok && rangeVal.GetListValue() != nil { + var events []ExtractedEvent + for _, evVal := range rangeVal.GetListValue().GetValues() { + evS := evVal.GetStructValue() + if evS == nil { + continue + } + evFields := evS.GetFields() + var ev ExtractedEvent + if intro, ok := evFields["introduced"]; ok { + ev.Introduced = intro.GetStringValue() + } + if fixed, ok := evFields["fixed"]; ok { + ev.Fixed = fixed.GetStringValue() + } + if la, ok := evFields["last_affected"]; ok { + ev.LastAffected = la.GetStringValue() + } + if lim, ok := evFields["limit"]; ok { + ev.Limit = lim.GetStringValue() + } + events = append(events, ev) + } + + return events + } + + // Fallback to old flat structure (single event) var ev ExtractedEvent if intro, ok := fields["introduced"]; ok { ev.Introduced = intro.GetStringValue() @@ -634,7 +663,11 @@ func parseExtractedEvent(v *structpb.Value) ExtractedEvent { ev.Limit = lim.GetStringValue() } - return ev + if ev != (ExtractedEvent{}) { + return []ExtractedEvent{ev} + } + + return nil } func parseExtractedEvents(r *osvschema.Range) []ExtractedEvent { @@ -642,9 +675,9 @@ func parseExtractedEvents(r *osvschema.Range) []ExtractedEvent { if len(rawValues) == 0 { return nil } - events := make([]ExtractedEvent, 0, len(rawValues)) + var events []ExtractedEvent for _, val := range rawValues { - events = append(events, parseExtractedEvent(val)) + events = append(events, parseExtractedEvent(val)...) } return events @@ -695,6 +728,24 @@ func isCPERange(r *osvschema.Range) bool { if fields == nil { return false } + + // Check new location inside extracted_events first + if extractedEventsVal, ok := fields["extracted_events"]; ok && extractedEventsVal.GetListValue() != nil { + for _, groupVal := range extractedEventsVal.GetListValue().GetValues() { + groupS := groupVal.GetStructValue() + if groupS == nil { + continue + } + groupFields := groupS.GetFields() + if sourceVal, ok := groupFields["source"]; ok { + if sourceVal.GetStringValue() == "CPE_RANGE" { + return true + } + } + } + } + + // Fallback to old location val, ok := fields["source"] if !ok { return false diff --git a/vulnfeeds/conversion/common.go b/vulnfeeds/conversion/common.go index 484e2058fe2..76c1008bcea 100644 --- a/vulnfeeds/conversion/common.go +++ b/vulnfeeds/conversion/common.go @@ -230,14 +230,17 @@ func GitVersionsToCommits(versionRanges []models.RangeWithMetadata, repos []stri } successfulRepos = append(successfulRepos, repo) if len(vr.Range.GetEvents()) > 0 { - dbSpecificMap := map[string]any{ - "extracted_events": vr.Range.GetEvents(), + extractedEventGroup := map[string]any{ + "range": vr.Range.GetEvents(), } if vr.Metadata.CPE != "" { - dbSpecificMap["cpe"] = vr.Metadata.CPE + extractedEventGroup["cpe"] = vr.Metadata.CPE } if string(vr.Metadata.Source) != "" { - dbSpecificMap["source"] = string(vr.Metadata.Source) + extractedEventGroup["source"] = string(vr.Metadata.Source) + } + dbSpecificMap := map[string]any{ + "extracted_events": []any{extractedEventGroup}, } databaseSpecific, err := utility.NewStructpbFromMap(dbSpecificMap) if err != nil { @@ -495,6 +498,7 @@ func CreateUnresolvedRanges(unresolvedRanges []models.RangeWithMetadata) *struct type key struct { Source string VendorProduct string + OriginalTag string } rangesByKey := make(map[key][]models.RangeWithMetadata) @@ -509,7 +513,7 @@ func CreateUnresolvedRanges(unresolvedRanges []models.RangeWithMetadata) *struct vendorProduct = ur.Metadata.CPE } } - k := key{Source: string(ur.Metadata.Source), VendorProduct: vendorProduct} + k := key{Source: string(ur.Metadata.Source), VendorProduct: vendorProduct, OriginalTag: ur.Metadata.OriginalTag} if _, ok := rangesByKey[k]; !ok { keys = append(keys, k) } @@ -520,8 +524,11 @@ func CreateUnresolvedRanges(unresolvedRanges []models.RangeWithMetadata) *struct if a.Source != b.Source { return strings.Compare(a.Source, b.Source) } + if a.VendorProduct != b.VendorProduct { + return strings.Compare(a.VendorProduct, b.VendorProduct) + } - return strings.Compare(a.VendorProduct, b.VendorProduct) + return strings.Compare(a.OriginalTag, b.OriginalTag) }) listElements := make([]any, 0, len(keys)) @@ -562,14 +569,21 @@ func CreateUnresolvedRanges(unresolvedRanges []models.RangeWithMetadata) *struct if k.VendorProduct != "" { unresolvedRangesMap["vendor_product"] = k.VendorProduct } - if k.Source != "" { - unresolvedRangesMap["source"] = k.Source - } if len(cpes) > 0 { unresolvedRangesMap["cpes"] = cpes } - unresolvedRangesMap["extracted_events"] = events + extractedEventGroup := map[string]any{ + "range": events, + } + if k.Source != "" { + extractedEventGroup["source"] = k.Source + } + if k.OriginalTag != "" { + extractedEventGroup["original_tag"] = k.OriginalTag + } + + unresolvedRangesMap["extracted_events"] = []any{extractedEventGroup} listElements = append(listElements, unresolvedRangesMap) } diff --git a/vulnfeeds/conversion/common_test.go b/vulnfeeds/conversion/common_test.go index 162e807ee1d..be40992cc77 100644 --- a/vulnfeeds/conversion/common_test.go +++ b/vulnfeeds/conversion/common_test.go @@ -381,7 +381,6 @@ func TestCreateUnresolvedRanges(t *testing.T) { StructValue: &structpb.Struct{ Fields: map[string]*structpb.Value{ "vendor_product": structpb.NewStringValue("another:app"), - "source": structpb.NewStringValue(string(models.VersionSourceCPE)), "cpes": structpb.NewListValue(&structpb.ListValue{ Values: []*structpb.Value{ structpb.NewStringValue("cpe:2.3:a:another:app:*:*:*:*:*:*:*:*"), @@ -395,7 +394,20 @@ func TestCreateUnresolvedRanges(t *testing.T) { Kind: &structpb.Value_StructValue{ StructValue: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "fixed": structpb.NewStringValue("2.0"), + "source": structpb.NewStringValue(string(models.VersionSourceCPE)), + "range": structpb.NewListValue(&structpb.ListValue{ + Values: []*structpb.Value{ + { + Kind: &structpb.Value_StructValue{ + StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "fixed": structpb.NewStringValue("2.0"), + }, + }, + }, + }, + }, + }), }, }, }, @@ -413,7 +425,6 @@ func TestCreateUnresolvedRanges(t *testing.T) { StructValue: &structpb.Struct{ Fields: map[string]*structpb.Value{ "vendor_product": structpb.NewStringValue("example:app"), - "source": structpb.NewStringValue(string(models.VersionSourceDescription)), "cpes": structpb.NewListValue(&structpb.ListValue{ Values: []*structpb.Value{ structpb.NewStringValue("cpe:2.3:a:example:app:*:*:*:*:*:*:*:*"), @@ -427,7 +438,20 @@ func TestCreateUnresolvedRanges(t *testing.T) { Kind: &structpb.Value_StructValue{ StructValue: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "introduced": structpb.NewStringValue("1.0"), + "source": structpb.NewStringValue(string(models.VersionSourceDescription)), + "range": structpb.NewListValue(&structpb.ListValue{ + Values: []*structpb.Value{ + { + Kind: &structpb.Value_StructValue{ + StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "introduced": structpb.NewStringValue("1.0"), + }, + }, + }, + }, + }, + }), }, }, }, diff --git a/vulnfeeds/conversion/cve5/__snapshots__/converter_test.snap b/vulnfeeds/conversion/cve5/__snapshots__/converter_test.snap index 8d068fe9df1..0634a5f5603 100755 --- a/vulnfeeds/conversion/cve5/__snapshots__/converter_test.snap +++ b/vulnfeeds/conversion/cve5/__snapshots__/converter_test.snap @@ -29,13 +29,17 @@ "database_specific": { "extracted_events": [ { - "introduced": "18.0" - }, - { - "fixed": "18.0.1" + "range": [ + { + "introduced": "18.0" + }, + { + "fixed": "18.0.1" + } + ], + "source": "AFFECTED_FIELD" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -100,13 +104,17 @@ "database_specific": { "extracted_events": [ { - "introduced": "0" - }, - { - "fixed": "1.10.5" + "range": [ + { + "introduced": "0" + }, + { + "fixed": "1.10.5" + } + ], + "source": "AFFECTED_FIELD" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -347,13 +355,96 @@ "database_specific": { "extracted_events": [ { - "introduced": "0" - }, + "range": [ + { + "fixed": "62e803b36173fd096d7ad460dd1d1db9be542593" + } + ], + "source": "REFERENCES_COMMIT" + } + ] + }, + "events": [ + { + "introduced": "0" + }, + { + "fixed": "62e803b36173fd096d7ad460dd1d1db9be542593" + } + ], + "repo": "https://github.com/harfbuzz/harfbuzz", + "type": "GIT" + } + ] + } + ], + "database_specific": { + "cna_assigner": "mitre", + "osv_generated_from": "unknown" + }, + "details": "An integer overflow in the component hb-ot-shape-fallback.cc of Harfbuzz v4.3.0 allows attackers to cause a Denial of Service (DoS) via unspecified vectors.", + "id": "CVE-2022-33068", + "modified": "2024-08-03T08:01:19.054Z", + "published": "2022-06-22T13:24:42Z", + "references": [ + { + "type": "FIX", + "url": "https://github.com/harfbuzz/harfbuzz/commit/62e803b36173fd096d7ad460dd1d1db9be542593" + }, + { + "type": "REPORT", + "url": "https://github.com/harfbuzz/harfbuzz/issues/3557" + }, + { + "type": "ADVISORY", + "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/FQBJ24W6TXLSAQWCFW7IBGUMX4AJI3S4/" + }, + { + "type": "ADVISORY", + "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/QQMEXOVDL3T2UXKBCON7JSOCE646G7HG/" + }, + { + "type": "ADVISORY", + "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/W56WTC5IY4EIUHVUIHMCXA3BSBZLSZCI/" + }, + { + "type": "ADVISORY", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-33068" + }, + { + "type": "ADVISORY", + "url": "https://security.gentoo.org/glsa/202209-11" + } + ], + "schema_version": "1.0.0" +} +{ + "affected": [ + { + "ranges": [ + { + "database_specific": { + "extracted_events": [ { - "fixed": "2.0.0-next.193" + "range": [ + { + "introduced": "0" + }, + { + "fixed": "2.0.0-next.193" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "fixed": "2c1762b85acb84467ed5e799afe1499cd2f912e6" + } + ], + "source": "REFERENCES_COMMIT" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -361,6 +452,9 @@ }, { "fixed": "eeda4f90af57368584fa97250cbb0d5bf0a5e16e" + }, + { + "fixed": "2c1762b85acb84467ed5e799afe1499cd2f912e6" } ], "repo": "https://github.com/lobehub/lobehub", @@ -417,19 +511,47 @@ "database_specific": { "extracted_events": [ { - "introduced": "0" - }, - { - "fixed": "4.25.8" - }, - { - "fixed": "5.29.5" - }, - { - "fixed": "6.31.1" + "range": [ + { + "introduced": "0" + }, + { + "fixed": "4.25.8" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "0" + }, + { + "fixed": "5.29.5" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "0" + }, + { + "fixed": "6.31.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "fixed": "17838beda2943d08b8a9d4df5b68f5f04f26d901" + } + ], + "source": "REFERENCES_COMMIT" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -443,6 +565,9 @@ }, { "fixed": "74211c0dfc2777318ab53c2cd2c317a2ef9012de" + }, + { + "fixed": "17838beda2943d08b8a9d4df5b68f5f04f26d901" } ], "repo": "https://github.com/protocolbuffers/protobuf", @@ -497,13 +622,26 @@ "database_specific": { "extracted_events": [ { - "introduced": "0" - }, - { - "last_affected": "1.25.3" + "range": [ + { + "introduced": "0" + }, + { + "last_affected": "1.25.3" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "original_tag": "v1.25.4", + "range": [ + { + "fixed": "369830bada2fd8826a5135cb2fc66660a9bef708" + } + ], + "source": "REFERENCES_TAG" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -511,6 +649,9 @@ }, { "last_affected": "9a7cfd8620989d9de6dc4ca0c95d9fd42c1768ed" + }, + { + "fixed": "369830bada2fd8826a5135cb2fc66660a9bef708" } ], "repo": "https://github.com/go-gitea/gitea", @@ -577,25 +718,48 @@ "database_specific": { "extracted_events": [ { - "introduced": "1.7.0" - }, - { - "fixed": "1.18.4" - }, - { - "introduced": "1.19.0" - }, - { - "fixed": "1.20.3" - }, - { - "introduced": "1.21.0" - }, - { - "fixed": "1.23.1" + "range": [ + { + "introduced": "1.7.0" + }, + { + "fixed": "1.18.4" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "1.19.0" + }, + { + "fixed": "1.20.3" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "1.21.0" + }, + { + "fixed": "1.23.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "original_tag": "tokio-1.23.1", + "range": [ + { + "fixed": "1a997ffbd62334af2553775234e75ede2d7d949f" + } + ], + "source": "REFERENCES_TAG" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -676,19 +840,36 @@ "database_specific": { "extracted_events": [ { - "introduced": "2.0.0" - }, - { - "fixed": "2.0.7" - }, - { - "introduced": "0" - }, - { - "fixed": "1.26.18" + "range": [ + { + "introduced": "2.0.0" + }, + { + "fixed": "2.0.7" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "0" + }, + { + "fixed": "1.26.18" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "fixed": "4e98d57809dacab1cbe625fddeec1a290c478ea9" + } + ], + "source": "REFERENCES_COMMIT" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -702,6 +883,9 @@ }, { "fixed": "9c2c2307dd1d6af504e09aac0326d86ee3597a0b" + }, + { + "fixed": "4e98d57809dacab1cbe625fddeec1a290c478ea9" } ], "repo": "https://github.com/urllib3/urllib3", @@ -771,13 +955,34 @@ "database_specific": { "extracted_events": [ { - "introduced": "4.x" - }, - { - "last_affected": "4.x" + "range": [ + { + "introduced": "4.x" + }, + { + "last_affected": "4.x" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "fixed": "83b3e91e0c1e84873a6d3ca3c5887eb5b4f5a3d8" + } + ], + "source": "REFERENCES_COMMIT" + }, + { + "original_tag": "v5.0.0", + "range": [ + { + "fixed": "e4dd3fa3182d0fd382e229e0c25d1bfd8b77a711" + } + ], + "source": "REFERENCES_TAG" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -785,6 +990,12 @@ }, { "last_affected": "85c43e41805cde051a7a29aefcac2cd6aee8c69d" + }, + { + "fixed": "83b3e91e0c1e84873a6d3ca3c5887eb5b4f5a3d8" + }, + { + "fixed": "e4dd3fa3182d0fd382e229e0c25d1bfd8b77a711" } ], "repo": "https://github.com/forcedotcom/salesforcemobilesdk-windows", @@ -846,19 +1057,28 @@ "database_specific": { "extracted_events": [ { - "introduced": "5.6.0" - }, - { - "last_affected": "5.6.0" - }, - { - "introduced": "5.6.1" - }, - { - "last_affected": "5.6.1" + "range": [ + { + "introduced": "5.6.0" + }, + { + "last_affected": "5.6.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "5.6.1" + }, + { + "last_affected": "5.6.1" + } + ], + "source": "AFFECTED_FIELD" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -1147,577 +1367,1059 @@ "database_specific": { "extracted_events": [ { - "introduced": "8.9.0" - }, - { - "last_affected": "8.9.0" - }, - { - "introduced": "8.8.0" - }, - { - "last_affected": "8.8.0" - }, - { - "introduced": "8.7.1" - }, - { - "last_affected": "8.7.1" - }, - { - "introduced": "8.7.0" - }, - { - "last_affected": "8.7.0" - }, - { - "introduced": "8.6.0" - }, - { - "last_affected": "8.6.0" - }, - { - "introduced": "8.5.0" - }, - { - "last_affected": "8.5.0" - }, - { - "introduced": "8.4.0" - }, - { - "last_affected": "8.4.0" - }, - { - "introduced": "8.3.0" - }, - { - "last_affected": "8.3.0" - }, - { - "introduced": "8.2.1" - }, - { - "last_affected": "8.2.1" - }, - { - "introduced": "8.2.0" - }, - { - "last_affected": "8.2.0" - }, - { - "introduced": "8.1.2" - }, - { - "last_affected": "8.1.2" - }, - { - "introduced": "8.1.1" - }, - { - "last_affected": "8.1.1" - }, - { - "introduced": "8.1.0" - }, - { - "last_affected": "8.1.0" - }, - { - "introduced": "8.0.1" - }, - { - "last_affected": "8.0.1" - }, - { - "introduced": "8.0.0" - }, - { - "last_affected": "8.0.0" - }, - { - "introduced": "7.88.1" - }, - { - "last_affected": "7.88.1" - }, - { - "introduced": "7.88.0" - }, - { - "last_affected": "7.88.0" - }, - { - "introduced": "7.87.0" - }, - { - "last_affected": "7.87.0" - }, - { - "introduced": "7.86.0" - }, - { - "last_affected": "7.86.0" - }, - { - "introduced": "7.85.0" - }, - { - "last_affected": "7.85.0" - }, - { - "introduced": "7.84.0" - }, - { - "last_affected": "7.84.0" - }, - { - "introduced": "7.83.1" - }, - { - "last_affected": "7.83.1" - }, - { - "introduced": "7.83.0" - }, - { - "last_affected": "7.83.0" - }, - { - "introduced": "7.82.0" - }, - { - "last_affected": "7.82.0" - }, - { - "introduced": "7.81.0" - }, - { - "last_affected": "7.81.0" - }, - { - "introduced": "7.80.0" - }, - { - "last_affected": "7.80.0" - }, - { - "introduced": "7.79.1" - }, - { - "last_affected": "7.79.1" - }, - { - "introduced": "7.79.0" - }, - { - "last_affected": "7.79.0" - }, - { - "introduced": "7.78.0" - }, - { - "last_affected": "7.78.0" - }, - { - "introduced": "7.77.0" - }, - { - "last_affected": "7.77.0" - }, - { - "introduced": "7.76.1" - }, - { - "last_affected": "7.76.1" - }, - { - "introduced": "7.76.0" - }, - { - "last_affected": "7.76.0" - }, - { - "introduced": "7.75.0" - }, - { - "last_affected": "7.75.0" - }, - { - "introduced": "7.74.0" - }, - { - "last_affected": "7.74.0" - }, - { - "introduced": "7.73.0" - }, - { - "last_affected": "7.73.0" - }, - { - "introduced": "7.72.0" - }, - { - "last_affected": "7.72.0" - }, - { - "introduced": "7.71.1" - }, - { - "last_affected": "7.71.1" - }, - { - "introduced": "7.71.0" - }, - { - "last_affected": "7.71.0" - }, - { - "introduced": "7.70.0" - }, - { - "last_affected": "7.70.0" - }, - { - "introduced": "7.69.1" - }, - { - "last_affected": "7.69.1" - }, - { - "introduced": "7.69.0" - }, - { - "last_affected": "7.69.0" - }, - { - "introduced": "7.68.0" - }, - { - "last_affected": "7.68.0" - }, - { - "introduced": "7.67.0" - }, - { - "last_affected": "7.67.0" - }, - { - "introduced": "7.66.0" - }, - { - "last_affected": "7.66.0" - }, - { - "introduced": "7.65.3" - }, - { - "last_affected": "7.65.3" - }, - { - "introduced": "7.65.2" - }, - { - "last_affected": "7.65.2" - }, - { - "introduced": "7.65.1" - }, - { - "last_affected": "7.65.1" - }, - { - "introduced": "7.65.0" - }, - { - "last_affected": "7.65.0" - }, - { - "introduced": "7.64.1" - }, - { - "last_affected": "7.64.1" - }, - { - "introduced": "7.64.0" - }, - { - "last_affected": "7.64.0" - }, - { - "introduced": "7.63.0" - }, - { - "last_affected": "7.63.0" - }, - { - "introduced": "7.62.0" - }, - { - "last_affected": "7.62.0" - }, - { - "introduced": "7.61.1" - }, - { - "last_affected": "7.61.1" - }, - { - "introduced": "7.61.0" - }, - { - "last_affected": "7.61.0" - }, - { - "introduced": "7.60.0" - }, - { - "last_affected": "7.60.0" - }, - { - "introduced": "7.59.0" - }, - { - "last_affected": "7.59.0" - }, - { - "introduced": "7.58.0" - }, - { - "last_affected": "7.58.0" - }, - { - "introduced": "7.57.0" - }, - { - "last_affected": "7.57.0" - }, - { - "introduced": "7.56.1" - }, - { - "last_affected": "7.56.1" - }, - { - "introduced": "7.56.0" - }, - { - "last_affected": "7.56.0" - }, - { - "introduced": "7.55.1" - }, - { - "last_affected": "7.55.1" - }, - { - "introduced": "7.55.0" - }, - { - "last_affected": "7.55.0" - }, - { - "introduced": "7.54.1" - }, - { - "last_affected": "7.54.1" - }, - { - "introduced": "7.54.0" - }, - { - "last_affected": "7.54.0" - }, - { - "introduced": "7.53.1" - }, - { - "last_affected": "7.53.1" - }, - { - "introduced": "7.53.0" - }, - { - "last_affected": "7.53.0" - }, - { - "introduced": "7.52.1" - }, - { - "last_affected": "7.52.1" - }, - { - "introduced": "7.52.0" - }, - { - "last_affected": "7.52.0" - }, - { - "introduced": "7.51.0" - }, - { - "last_affected": "7.51.0" - }, - { - "introduced": "7.50.3" - }, - { - "last_affected": "7.50.3" - }, - { - "introduced": "7.50.2" - }, - { - "last_affected": "7.50.2" - }, - { - "introduced": "7.50.1" - }, - { - "last_affected": "7.50.1" - }, - { - "introduced": "7.50.0" - }, - { - "last_affected": "7.50.0" - }, - { - "introduced": "7.49.1" - }, - { - "last_affected": "7.49.1" - }, - { - "introduced": "7.49.0" - }, - { - "last_affected": "7.49.0" - }, - { - "introduced": "7.48.0" - }, - { - "last_affected": "7.48.0" - }, - { - "introduced": "7.47.1" - }, - { - "last_affected": "7.47.1" - }, - { - "introduced": "7.47.0" - }, - { - "last_affected": "7.47.0" - }, - { - "introduced": "7.46.0" - }, - { - "last_affected": "7.46.0" - }, - { - "introduced": "7.45.0" - }, - { - "last_affected": "7.45.0" - }, - { - "introduced": "7.44.0" - }, - { - "last_affected": "7.44.0" - }, - { - "introduced": "7.43.0" - }, - { - "last_affected": "7.43.0" - }, - { - "introduced": "7.42.1" - }, - { - "last_affected": "7.42.1" - }, - { - "introduced": "7.42.0" - }, - { - "last_affected": "7.42.0" - }, - { - "introduced": "7.41.0" - }, - { - "last_affected": "7.41.0" - }, - { - "introduced": "7.40.0" - }, - { - "last_affected": "7.40.0" - }, - { - "introduced": "7.39.0" - }, - { - "last_affected": "7.39.0" - }, - { - "introduced": "7.38.0" - }, - { - "last_affected": "7.38.0" - }, - { - "introduced": "7.37.1" - }, - { - "last_affected": "7.37.1" - }, - { - "introduced": "7.37.0" - }, - { - "last_affected": "7.37.0" - }, - { - "introduced": "7.36.0" - }, - { - "last_affected": "7.36.0" - }, - { - "introduced": "7.35.0" - }, - { - "last_affected": "7.35.0" - }, - { - "introduced": "7.34.0" - }, - { - "last_affected": "7.34.0" - }, - { - "introduced": "7.33.0" - }, - { - "last_affected": "7.33.0" - }, - { - "introduced": "7.32.0" - }, - { - "last_affected": "7.32.0" + "range": [ + { + "introduced": "8.9.0" + }, + { + "last_affected": "8.9.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.8.0" + }, + { + "last_affected": "8.8.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.7.1" + }, + { + "last_affected": "8.7.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.7.0" + }, + { + "last_affected": "8.7.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.6.0" + }, + { + "last_affected": "8.6.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.5.0" + }, + { + "last_affected": "8.5.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.4.0" + }, + { + "last_affected": "8.4.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.3.0" + }, + { + "last_affected": "8.3.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.2.1" + }, + { + "last_affected": "8.2.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.2.0" + }, + { + "last_affected": "8.2.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.1.2" + }, + { + "last_affected": "8.1.2" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.1.1" + }, + { + "last_affected": "8.1.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.1.0" + }, + { + "last_affected": "8.1.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.0.1" + }, + { + "last_affected": "8.0.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "8.0.0" + }, + { + "last_affected": "8.0.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.88.1" + }, + { + "last_affected": "7.88.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.88.0" + }, + { + "last_affected": "7.88.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.87.0" + }, + { + "last_affected": "7.87.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.86.0" + }, + { + "last_affected": "7.86.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.85.0" + }, + { + "last_affected": "7.85.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.84.0" + }, + { + "last_affected": "7.84.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.83.1" + }, + { + "last_affected": "7.83.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.83.0" + }, + { + "last_affected": "7.83.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.82.0" + }, + { + "last_affected": "7.82.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.81.0" + }, + { + "last_affected": "7.81.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.80.0" + }, + { + "last_affected": "7.80.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.79.1" + }, + { + "last_affected": "7.79.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.79.0" + }, + { + "last_affected": "7.79.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.78.0" + }, + { + "last_affected": "7.78.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.77.0" + }, + { + "last_affected": "7.77.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.76.1" + }, + { + "last_affected": "7.76.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.76.0" + }, + { + "last_affected": "7.76.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.75.0" + }, + { + "last_affected": "7.75.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.74.0" + }, + { + "last_affected": "7.74.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.73.0" + }, + { + "last_affected": "7.73.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.72.0" + }, + { + "last_affected": "7.72.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.71.1" + }, + { + "last_affected": "7.71.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.71.0" + }, + { + "last_affected": "7.71.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.70.0" + }, + { + "last_affected": "7.70.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.69.1" + }, + { + "last_affected": "7.69.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.69.0" + }, + { + "last_affected": "7.69.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.68.0" + }, + { + "last_affected": "7.68.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.67.0" + }, + { + "last_affected": "7.67.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.66.0" + }, + { + "last_affected": "7.66.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.65.3" + }, + { + "last_affected": "7.65.3" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.65.2" + }, + { + "last_affected": "7.65.2" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.65.1" + }, + { + "last_affected": "7.65.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.65.0" + }, + { + "last_affected": "7.65.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.64.1" + }, + { + "last_affected": "7.64.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.64.0" + }, + { + "last_affected": "7.64.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.63.0" + }, + { + "last_affected": "7.63.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.62.0" + }, + { + "last_affected": "7.62.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.61.1" + }, + { + "last_affected": "7.61.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.61.0" + }, + { + "last_affected": "7.61.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.60.0" + }, + { + "last_affected": "7.60.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.59.0" + }, + { + "last_affected": "7.59.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.58.0" + }, + { + "last_affected": "7.58.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.57.0" + }, + { + "last_affected": "7.57.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.56.1" + }, + { + "last_affected": "7.56.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.56.0" + }, + { + "last_affected": "7.56.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.55.1" + }, + { + "last_affected": "7.55.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.55.0" + }, + { + "last_affected": "7.55.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.54.1" + }, + { + "last_affected": "7.54.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.54.0" + }, + { + "last_affected": "7.54.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.53.1" + }, + { + "last_affected": "7.53.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.53.0" + }, + { + "last_affected": "7.53.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.52.1" + }, + { + "last_affected": "7.52.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.52.0" + }, + { + "last_affected": "7.52.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.51.0" + }, + { + "last_affected": "7.51.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.50.3" + }, + { + "last_affected": "7.50.3" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.50.2" + }, + { + "last_affected": "7.50.2" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.50.1" + }, + { + "last_affected": "7.50.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.50.0" + }, + { + "last_affected": "7.50.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.49.1" + }, + { + "last_affected": "7.49.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.49.0" + }, + { + "last_affected": "7.49.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.48.0" + }, + { + "last_affected": "7.48.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.47.1" + }, + { + "last_affected": "7.47.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.47.0" + }, + { + "last_affected": "7.47.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.46.0" + }, + { + "last_affected": "7.46.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.45.0" + }, + { + "last_affected": "7.45.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.44.0" + }, + { + "last_affected": "7.44.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.43.0" + }, + { + "last_affected": "7.43.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.42.1" + }, + { + "last_affected": "7.42.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.42.0" + }, + { + "last_affected": "7.42.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.41.0" + }, + { + "last_affected": "7.41.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.40.0" + }, + { + "last_affected": "7.40.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.39.0" + }, + { + "last_affected": "7.39.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.38.0" + }, + { + "last_affected": "7.38.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.37.1" + }, + { + "last_affected": "7.37.1" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.37.0" + }, + { + "last_affected": "7.37.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.36.0" + }, + { + "last_affected": "7.36.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.35.0" + }, + { + "last_affected": "7.35.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.34.0" + }, + { + "last_affected": "7.34.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.33.0" + }, + { + "last_affected": "7.33.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "introduced": "7.32.0" + }, + { + "last_affected": "7.32.0" + } + ], + "source": "AFFECTED_FIELD" + }, + { + "range": [ + { + "fixed": "27959ecce75cdb2809c0bdb3286e60e08fadb519" + } + ], + "source": "REFERENCES_COMMIT" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -1725,6 +2427,9 @@ }, { "last_affected": "70812c2f32fc5734bcbbe572b9f61c380433ad6a" + }, + { + "fixed": "27959ecce75cdb2809c0bdb3286e60e08fadb519" } ], "repo": "https://github.com/curl/curl", @@ -1885,47 +2590,6 @@ ], "summary": "ASN.1 date parser overread" } -{ - "database_specific": { - "cna_assigner": "mitre", - "osv_generated_from": "unknown" - }, - "details": "An integer overflow in the component hb-ot-shape-fallback.cc of Harfbuzz v4.3.0 allows attackers to cause a Denial of Service (DoS) via unspecified vectors.", - "id": "CVE-2022-33068", - "modified": "2024-08-03T08:01:19.054Z", - "published": "2022-06-22T13:24:42Z", - "references": [ - { - "type": "FIX", - "url": "https://github.com/harfbuzz/harfbuzz/commit/62e803b36173fd096d7ad460dd1d1db9be542593" - }, - { - "type": "REPORT", - "url": "https://github.com/harfbuzz/harfbuzz/issues/3557" - }, - { - "type": "ADVISORY", - "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/FQBJ24W6TXLSAQWCFW7IBGUMX4AJI3S4/" - }, - { - "type": "ADVISORY", - "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/QQMEXOVDL3T2UXKBCON7JSOCE646G7HG/" - }, - { - "type": "ADVISORY", - "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/W56WTC5IY4EIUHVUIHMCXA3BSBZLSZCI/" - }, - { - "type": "ADVISORY", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-33068" - }, - { - "type": "ADVISORY", - "url": "https://security.gentoo.org/glsa/202209-11" - } - ], - "schema_version": "1.0.0" -} { "database_specific": { "cna_assigner": "mitre", diff --git a/vulnfeeds/conversion/cve5/default_extractor.go b/vulnfeeds/conversion/cve5/default_extractor.go index e3ae9a621f0..ca5ff2ef24c 100644 --- a/vulnfeeds/conversion/cve5/default_extractor.go +++ b/vulnfeeds/conversion/cve5/default_extractor.go @@ -2,6 +2,7 @@ package cve5 import ( "maps" + "net/http" "slices" "strings" @@ -86,9 +87,15 @@ func (d *DefaultVersionExtractor) ExtractVersions(cve models.CVE5, v *vulns.Vuln } } + references := identifyPossibleURLs(cve) + commits, err := c.ExtractCommitsFromRefs(references, http.DefaultClient, repoTagsCache) + if err != nil { + metrics.AddNote("Failed to extract commits from references: %v", err) + } + keys := slices.Collect(maps.Keys(successfulRepos)) groupedRanges := c.GroupRanges(resolvedRanges) - affected := c.MergeRangesAndCreateAffected(groupedRanges, nil, keys, metrics) + affected := c.MergeRangesAndCreateAffected(groupedRanges, commits, keys, metrics) v.Affected = append(v.Affected, affected...) if len(unresolvedRanges) > 0 { diff --git a/vulnfeeds/conversion/cve5/version_extraction_test.go b/vulnfeeds/conversion/cve5/version_extraction_test.go index b3fc79fe8b4..d4795d8a795 100644 --- a/vulnfeeds/conversion/cve5/version_extraction_test.go +++ b/vulnfeeds/conversion/cve5/version_extraction_test.go @@ -429,7 +429,6 @@ func TestExtractVersions(t *testing.T) { }, DatabaseSpecific: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "source": structpb.NewStringValue("AFFECTED_FIELD"), "extracted_events": { Kind: &structpb.Value_ListValue{ ListValue: &structpb.ListValue{ @@ -438,16 +437,33 @@ func TestExtractVersions(t *testing.T) { Kind: &structpb.Value_StructValue{ StructValue: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "introduced": structpb.NewStringValue("18.0"), - }, - }, - }, - }, - { - Kind: &structpb.Value_StructValue{ - StructValue: &structpb.Struct{ - Fields: map[string]*structpb.Value{ - "fixed": structpb.NewStringValue("18.0.1"), + "source": structpb.NewStringValue("AFFECTED_FIELD"), + "range": { + Kind: &structpb.Value_ListValue{ + ListValue: &structpb.ListValue{ + Values: []*structpb.Value{ + { + Kind: &structpb.Value_StructValue{ + StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "introduced": structpb.NewStringValue("18.0"), + }, + }, + }, + }, + { + Kind: &structpb.Value_StructValue{ + StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "fixed": structpb.NewStringValue("18.0.1"), + }, + }, + }, + }, + }, + }, + }, + }, }, }, }, @@ -475,7 +491,6 @@ func TestExtractVersions(t *testing.T) { }, DatabaseSpecific: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "source": structpb.NewStringValue("AFFECTED_FIELD"), "extracted_events": { Kind: &structpb.Value_ListValue{ ListValue: &structpb.ListValue{ @@ -484,16 +499,33 @@ func TestExtractVersions(t *testing.T) { Kind: &structpb.Value_StructValue{ StructValue: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "introduced": structpb.NewStringValue("0"), - }, - }, - }, - }, - { - Kind: &structpb.Value_StructValue{ - StructValue: &structpb.Struct{ - Fields: map[string]*structpb.Value{ - "fixed": structpb.NewStringValue("1.10.5"), + "source": structpb.NewStringValue("AFFECTED_FIELD"), + "range": { + Kind: &structpb.Value_ListValue{ + ListValue: &structpb.ListValue{ + Values: []*structpb.Value{ + { + Kind: &structpb.Value_StructValue{ + StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "introduced": structpb.NewStringValue("0"), + }, + }, + }, + }, + { + Kind: &structpb.Value_StructValue{ + StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "fixed": structpb.NewStringValue("1.10.5"), + }, + }, + }, + }, + }, + }, + }, + }, }, }, }, diff --git a/vulnfeeds/conversion/grouping.go b/vulnfeeds/conversion/grouping.go index d117f553147..5ef84b6fb8f 100644 --- a/vulnfeeds/conversion/grouping.go +++ b/vulnfeeds/conversion/grouping.go @@ -6,6 +6,7 @@ import ( "slices" "github.com/google/osv/vulnfeeds/models" + "github.com/google/osv/vulnfeeds/utility" "github.com/google/osv/vulnfeeds/utility/logger" "github.com/ossf/osv-schema/bindings/go/osvschema" "google.golang.org/protobuf/encoding/protojson" @@ -364,25 +365,37 @@ func MergeRangesAndCreateAffected( if len(commits) > 0 { for _, commit := range commits { if commit.Repo == repo { + events := convertCommitToEvents(commit) if mergedRange == nil { mergedRange = BuildGitVersionRange(commit.Introduced, commit.LastAffected, commit.Fixed, repo) } else { - event := convertCommitToEvent(commit) - if event != nil { - addEventToRange(mergedRange, event) + for _, e := range events { + addEventToRange(mergedRange, e) } } - if mergedRange.GetDatabaseSpecific() == nil { - mergedRange.DatabaseSpecific = &structpb.Struct{ - Fields: make(map[string]*structpb.Value), + if len(events) > 0 { + source := commit.Source + if source == "" || source == models.VersionSourceNone { + source = models.VersionSourceRefs + } + extractedEventGroup := map[string]any{ + "range": events, + "source": string(source), + } + if commit.OriginalTag != "" { + extractedEventGroup["original_tag"] = commit.OriginalTag + } + dbSpecificMap := map[string]any{ + "extracted_events": []any{extractedEventGroup}, + } + dbSpecific, err := utility.NewStructpbFromMap(dbSpecificMap) + if err == nil { + mergeDatabaseSpecific(mergedRange, dbSpecific) + } else { + metrics.AddNote("failed to make database specific for commit: %v", err) } } - mergeDatabaseSpecific(mergedRange, &structpb.Struct{ - Fields: map[string]*structpb.Value{ - "source": structpb.NewStringValue(string(models.VersionSourceRefs)), - }, - }) } } } @@ -404,20 +417,39 @@ func MergeRangesAndCreateAffected( for _, commit := range commits { repo := commit.Repo + events := convertCommitToEvents(commit) if vr, ok := repoToRange[repo]; !ok { vr := BuildGitVersionRange(commit.Introduced, commit.LastAffected, commit.Fixed, repo) - vr.DatabaseSpecific = &structpb.Struct{ - Fields: map[string]*structpb.Value{ - "source": structpb.NewStringValue(string(models.VersionSourceRefs)), - }, - } repoToRange[repo] = vr repoOrder = append(repoOrder, repo) metrics.ResolvedRangesCount++ } else { - event := convertCommitToEvent(commit) - if event != nil { - addEventToRange(vr, event) + for _, e := range events { + addEventToRange(vr, e) + } + } + + if len(events) > 0 { + source := commit.Source + if source == "" || source == models.VersionSourceNone { + source = models.VersionSourceRefs + } + extractedEventGroup := map[string]any{ + "range": events, + "source": string(source), + } + if commit.OriginalTag != "" { + extractedEventGroup["original_tag"] = commit.OriginalTag + } + dbSpecificMap := map[string]any{ + "extracted_events": []any{extractedEventGroup}, + } + dbSpecific, err := utility.NewStructpbFromMap(dbSpecificMap) + if err == nil { + // mergeDatabaseSpecific handles nil DatabaseSpecific in target + mergeDatabaseSpecific(repoToRange[repo], dbSpecific) + } else { + metrics.AddNote("failed to make database specific for commit: %v", err) } } } @@ -464,26 +496,27 @@ func addEventToRange(versionRange *osvschema.Range, event *osvschema.Event) { } } -// convertCommitToEvent creates an OSV Event from an AffectedCommit. -// It returns an event with the Introduced, Fixed, or LastAffected value from the commit. -func convertCommitToEvent(commit models.AffectedCommit) *osvschema.Event { +// convertCommitToEvents creates OSV Events from an AffectedCommit. +// It returns a slice of events with the Introduced, Fixed, or LastAffected values from the commit. +func convertCommitToEvents(commit models.AffectedCommit) []*osvschema.Event { + var events []*osvschema.Event if commit.Introduced != "" { - return &osvschema.Event{ + events = append(events, &osvschema.Event{ Introduced: commit.Introduced, - } + }) } if commit.Fixed != "" { - return &osvschema.Event{ + events = append(events, &osvschema.Event{ Fixed: commit.Fixed, - } + }) } if commit.LastAffected != "" { - return &osvschema.Event{ + events = append(events, &osvschema.Event{ LastAffected: commit.LastAffected, - } + }) } - return nil + return events } func isStandaloneRange(vrwm models.RangeWithMetadata) bool { diff --git a/vulnfeeds/conversion/grouping_test.go b/vulnfeeds/conversion/grouping_test.go index cdf8b35d57c..de2c79a98aa 100644 --- a/vulnfeeds/conversion/grouping_test.go +++ b/vulnfeeds/conversion/grouping_test.go @@ -5,6 +5,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/osv/vulnfeeds/models" + "github.com/google/osv/vulnfeeds/utility" "github.com/ossf/osv-schema/bindings/go/osvschema" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/structpb" @@ -438,6 +439,15 @@ func TestGroupAffectedRanges(t *testing.T) { } func TestMergeRangesAndCreateAffected(t *testing.T) { + mustMakeDBSpecific := func(m map[string]any) *structpb.Struct { + ds, err := utility.NewStructpbFromMap(m) + if err != nil { + t.Fatalf("failed to make database specific: %v", err) + } + + return ds + } + tests := []struct { name string resolvedRanges []*osvschema.Range @@ -479,11 +489,18 @@ func TestMergeRangesAndCreateAffected(t *testing.T) { {Fixed: "1.0"}, {Fixed: "1.2"}, }, - DatabaseSpecific: &structpb.Struct{ - Fields: map[string]*structpb.Value{ - "source": structpb.NewStringValue("REFERENCES"), + DatabaseSpecific: mustMakeDBSpecific(map[string]any{ + "extracted_events": []any{ + map[string]any{ + "range": []*osvschema.Event{{Introduced: "1.1"}}, + "source": "REFERENCES", + }, + map[string]any{ + "range": []*osvschema.Event{{Fixed: "1.2"}}, + "source": "REFERENCES", + }, }, - }, + }), }, }, }, @@ -508,11 +525,14 @@ func TestMergeRangesAndCreateAffected(t *testing.T) { }, Repo: "repo2", Type: osvschema.Range_GIT, - DatabaseSpecific: &structpb.Struct{ - Fields: map[string]*structpb.Value{ - "source": structpb.NewStringValue("REFERENCES"), + DatabaseSpecific: mustMakeDBSpecific(map[string]any{ + "extracted_events": []any{ + map[string]any{ + "range": []*osvschema.Event{{Introduced: "0"}, {Fixed: "1.0"}}, + "source": "REFERENCES", + }, }, - }, + }), }, }, }, @@ -543,11 +563,14 @@ func TestMergeRangesAndCreateAffected(t *testing.T) { }, Repo: "repo_a", Type: osvschema.Range_GIT, - DatabaseSpecific: &structpb.Struct{ - Fields: map[string]*structpb.Value{ - "source": structpb.NewStringValue("REFERENCES"), + DatabaseSpecific: mustMakeDBSpecific(map[string]any{ + "extracted_events": []any{ + map[string]any{ + "range": []*osvschema.Event{{Introduced: "0.5"}}, + "source": "REFERENCES", + }, }, - }, + }), }, { Events: []*osvschema.Event{ @@ -556,11 +579,18 @@ func TestMergeRangesAndCreateAffected(t *testing.T) { }, Repo: "repo_b", Type: osvschema.Range_GIT, - DatabaseSpecific: &structpb.Struct{ - Fields: map[string]*structpb.Value{ - "source": structpb.NewStringValue("REFERENCES"), + DatabaseSpecific: mustMakeDBSpecific(map[string]any{ + "extracted_events": []any{ + map[string]any{ + "range": []*osvschema.Event{{Introduced: "0"}}, + "source": "REFERENCES", + }, + map[string]any{ + "range": []*osvschema.Event{{Fixed: "1.0"}}, + "source": "REFERENCES", + }, }, - }, + }), }, }, }, @@ -605,11 +635,22 @@ func TestMergeRangesAndCreateAffected(t *testing.T) { {Fixed: "1.0"}, {LastAffected: "0.5"}, }, - DatabaseSpecific: &structpb.Struct{ - Fields: map[string]*structpb.Value{ - "source": structpb.NewStringValue("REFERENCES"), + DatabaseSpecific: mustMakeDBSpecific(map[string]any{ + "extracted_events": []any{ + map[string]any{ + "range": []*osvschema.Event{{Fixed: "1.0"}}, + "source": "REFERENCES", + }, + map[string]any{ + "range": []*osvschema.Event{{Introduced: "0"}}, + "source": "REFERENCES", + }, + map[string]any{ + "range": []*osvschema.Event{{LastAffected: "0.5"}}, + "source": "REFERENCES", + }, }, - }, + }), }, }, }, @@ -683,11 +724,14 @@ func TestMergeRangesAndCreateAffected(t *testing.T) { {Fixed: "3.0"}, {Fixed: "4.0"}, }, - DatabaseSpecific: &structpb.Struct{ - Fields: map[string]*structpb.Value{ - "source": structpb.NewStringValue("REFERENCES"), + DatabaseSpecific: mustMakeDBSpecific(map[string]any{ + "extracted_events": []any{ + map[string]any{ + "range": []*osvschema.Event{{Fixed: "4.0"}}, + "source": "REFERENCES", + }, }, - }, + }), }, }, }, diff --git a/vulnfeeds/conversion/nvd/__snapshots__/converter_test.snap b/vulnfeeds/conversion/nvd/__snapshots__/converter_test.snap index d60d075e80d..50383a7b708 100755 --- a/vulnfeeds/conversion/nvd/__snapshots__/converter_test.snap +++ b/vulnfeeds/conversion/nvd/__snapshots__/converter_test.snap @@ -1757,18 +1757,28 @@ "ranges": [ { "database_specific": { - "cpe": "cpe:2.3:a:gitea:gitea:*:*:*:*:*:-:*:*", "extracted_events": [ { - "introduced": "0" - }, - { - "fixed": "1.25.4" + "cpe": "cpe:2.3:a:gitea:gitea:*:*:*:*:*:-:*:*", + "range": [ + { + "introduced": "0" + }, + { + "fixed": "1.25.4" + } + ], + "source": "CPE_RANGE" + }, + { + "original_tag": "v1.25.4", + "range": [ + { + "fixed": "369830bada2fd8826a5135cb2fc66660a9bef708" + } + ], + "source": "REFERENCES_TAG" } - ], - "source": [ - "CPE_RANGE", - "REFERENCES" ] }, "events": [ @@ -1831,30 +1841,52 @@ "ranges": [ { "database_specific": { - "cpe": "cpe:2.3:a:tokio:tokio:*:*:*:*:*:rust:*:*", "extracted_events": [ { - "introduced": "1.7.0" - }, - { - "fixed": "1.18.4" - }, - { - "introduced": "1.19.0" - }, - { - "fixed": "1.20.3" - }, - { - "introduced": "1.21.0" - }, - { - "fixed": "1.23.1" + "cpe": "cpe:2.3:a:tokio:tokio:*:*:*:*:*:rust:*:*", + "range": [ + { + "introduced": "1.7.0" + }, + { + "fixed": "1.18.4" + } + ], + "source": "CPE_RANGE" + }, + { + "cpe": "cpe:2.3:a:tokio:tokio:*:*:*:*:*:rust:*:*", + "range": [ + { + "introduced": "1.19.0" + }, + { + "fixed": "1.20.3" + } + ], + "source": "CPE_RANGE" + }, + { + "cpe": "cpe:2.3:a:tokio:tokio:*:*:*:*:*:rust:*:*", + "range": [ + { + "introduced": "1.21.0" + }, + { + "fixed": "1.23.1" + } + ], + "source": "CPE_RANGE" + }, + { + "original_tag": "tokio-1.23.1", + "range": [ + { + "fixed": "1a997ffbd62334af2553775234e75ede2d7d949f" + } + ], + "source": "REFERENCES_TAG" } - ], - "source": [ - "CPE_RANGE", - "REFERENCES" ] }, "events": [ @@ -1925,7 +1957,16 @@ "ranges": [ { "database_specific": { - "source": "REFERENCES" + "extracted_events": [ + { + "range": [ + { + "fixed": "2c1762b85acb84467ed5e799afe1499cd2f912e6" + } + ], + "source": "REFERENCES_COMMIT" + } + ] }, "events": [ { @@ -1975,30 +2016,51 @@ "ranges": [ { "database_specific": { - "cpe": "cpe:2.3:a:google:protobuf-python:*:*:*:*:*:*:*:*", "extracted_events": [ { - "introduced": "0" - }, - { - "fixed": "4.25.8" - }, - { - "introduced": "5.26.0" - }, - { - "fixed": "5.29.5" - }, - { - "introduced": "6.30.0" - }, - { - "fixed": "6.31.1" + "cpe": "cpe:2.3:a:google:protobuf-python:*:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "0" + }, + { + "fixed": "4.25.8" + } + ], + "source": "CPE_RANGE" + }, + { + "cpe": "cpe:2.3:a:google:protobuf-python:*:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "5.26.0" + }, + { + "fixed": "5.29.5" + } + ], + "source": "CPE_RANGE" + }, + { + "cpe": "cpe:2.3:a:google:protobuf-python:*:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "6.30.0" + }, + { + "fixed": "6.31.1" + } + ], + "source": "CPE_RANGE" + }, + { + "range": [ + { + "fixed": "17838beda2943d08b8a9d4df5b68f5f04f26d901" + } + ], + "source": "REFERENCES_COMMIT" } - ], - "source": [ - "CPE_RANGE", - "REFERENCES" ] }, "events": [ @@ -2057,16 +2119,20 @@ "ranges": [ { "database_specific": { - "cpe": "cpe:2.3:a:haxx:libcurl:*:*:*:*:*:*:*:*", "extracted_events": [ { - "introduced": "0" - }, - { - "fixed": "7.61.1" + "cpe": "cpe:2.3:a:haxx:libcurl:*:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "0" + }, + { + "fixed": "7.61.1" + } + ], + "source": "CPE_RANGE" } - ], - "source": "CPE_RANGE" + ] }, "events": [ { @@ -2429,18 +2495,27 @@ "ranges": [ { "database_specific": { - "cpe": "cpe:2.3:a:harfbuzz_project:harfbuzz:4.3.0:*:*:*:*:*:*:*", "extracted_events": [ { - "introduced": "4.3.0" - }, - { - "last_affected": "4.3.0" + "cpe": "cpe:2.3:a:harfbuzz_project:harfbuzz:4.3.0:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "4.3.0" + }, + { + "last_affected": "4.3.0" + } + ], + "source": "CPE_STRING" + }, + { + "range": [ + { + "fixed": "62e803b36173fd096d7ad460dd1d1db9be542593" + } + ], + "source": "REFERENCES_COMMIT" } - ], - "source": [ - "CPE_STRING", - "REFERENCES" ] }, "events": [ @@ -2486,6 +2561,21 @@ ], "source": "CPE_STRING", "vendor_product": "fedoraproject:fedora" + }, + { + "cpes": [ + "cpe:2.3:a:harfbuzz_project:harfbuzz:4.3.0:*:*:*:*:*:*:*" + ], + "extracted_events": [ + { + "introduced": "4.3.0" + }, + { + "last_affected": "4.3.0" + } + ], + "source": "CPE_STRING", + "vendor_product": "harfbuzz_project:harfbuzz" } ] }, @@ -2535,585 +2625,992 @@ "ranges": [ { "database_specific": { - "cpe": [ - "cpe:2.3:a:ffmpeg:ffmpeg:2.0:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.0.1:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.0.2:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.0.3:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.0.4:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.0.5:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.0.6:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.0.7:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.1:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.1.1:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.1.2:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.1.3:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.1.4:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.1.5:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.1.6:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.1.7:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.1.8:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.1:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.2:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.3:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.4:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.5:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.6:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.7:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.8:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.9:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.10:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.11:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.12:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.13:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.14:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.15:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.2.16:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.3:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.3.1:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.3.2:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.3.3:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.3.4:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.3.5:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.3.6:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.1:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.2:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.3:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.4:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.5:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.6:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.7:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.8:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.9:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.10:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.11:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.4.12:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.5:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.5.1:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.5.2:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.5.3:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.5.4:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.5.5:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.5.6:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.5.7:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.5.8:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.5.9:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.6:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.6.1:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.6.2:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.6.3:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.6.4:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.6.5:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.6.6:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.7:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.7.1:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.7.2:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.7.3:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.7.4:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.8:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.8:dev:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.8.1:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.8.2:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.8.3:*:*:*:*:*:*:*", - "cpe:2.3:a:ffmpeg:ffmpeg:2.8.4:*:*:*:*:*:*:*" - ], "extracted_events": [ { - "introduced": "2.0" - }, - { - "last_affected": "2.0" - }, - { - "introduced": "2.0.1" - }, - { - "last_affected": "2.0.1" - }, - { - "introduced": "2.0.2" - }, - { - "last_affected": "2.0.2" - }, - { - "introduced": "2.0.3" - }, - { - "last_affected": "2.0.3" - }, - { - "introduced": "2.0.4" - }, - { - "last_affected": "2.0.4" - }, - { - "introduced": "2.0.5" - }, - { - "last_affected": "2.0.5" - }, - { - "introduced": "2.0.6" - }, - { - "last_affected": "2.0.6" - }, - { - "introduced": "2.0.7" - }, - { - "last_affected": "2.0.7" - }, - { - "introduced": "2.1" - }, - { - "last_affected": "2.1" - }, - { - "introduced": "2.1.1" - }, - { - "last_affected": "2.1.1" - }, - { - "introduced": "2.1.2" - }, - { - "last_affected": "2.1.2" - }, - { - "introduced": "2.1.3" - }, - { - "last_affected": "2.1.3" - }, - { - "introduced": "2.1.4" - }, - { - "last_affected": "2.1.4" - }, - { - "introduced": "2.1.5" - }, - { - "last_affected": "2.1.5" - }, - { - "introduced": "2.1.6" - }, - { - "last_affected": "2.1.6" - }, - { - "introduced": "2.1.7" - }, - { - "last_affected": "2.1.7" - }, - { - "introduced": "2.1.8" - }, - { - "last_affected": "2.1.8" - }, - { - "introduced": "2.2" - }, - { - "last_affected": "2.2" - }, - { - "introduced": "2.2.1" - }, - { - "last_affected": "2.2.1" - }, - { - "introduced": "2.2.2" - }, - { - "last_affected": "2.2.2" - }, - { - "introduced": "2.2.3" - }, - { - "last_affected": "2.2.3" - }, - { - "introduced": "2.2.4" - }, - { - "last_affected": "2.2.4" - }, - { - "introduced": "2.2.5" - }, - { - "last_affected": "2.2.5" - }, - { - "introduced": "2.2.6" - }, - { - "last_affected": "2.2.6" - }, - { - "introduced": "2.2.7" - }, - { - "last_affected": "2.2.7" - }, - { - "introduced": "2.2.8" - }, - { - "last_affected": "2.2.8" - }, - { - "introduced": "2.2.9" - }, - { - "last_affected": "2.2.9" - }, - { - "introduced": "2.2.10" - }, - { - "last_affected": "2.2.10" - }, - { - "introduced": "2.2.11" - }, - { - "last_affected": "2.2.11" - }, - { - "introduced": "2.2.12" - }, - { - "last_affected": "2.2.12" - }, - { - "introduced": "2.2.13" - }, - { - "last_affected": "2.2.13" - }, - { - "introduced": "2.2.14" - }, - { - "last_affected": "2.2.14" - }, - { - "introduced": "2.2.15" - }, - { - "last_affected": "2.2.15" - }, - { - "introduced": "2.2.16" - }, - { - "last_affected": "2.2.16" - }, - { - "introduced": "2.3" - }, - { - "last_affected": "2.3" - }, - { - "introduced": "2.3.1" - }, - { - "last_affected": "2.3.1" - }, - { - "introduced": "2.3.2" - }, - { - "last_affected": "2.3.2" - }, - { - "introduced": "2.3.3" - }, - { - "last_affected": "2.3.3" - }, - { - "introduced": "2.3.4" - }, - { - "last_affected": "2.3.4" - }, - { - "introduced": "2.3.5" - }, - { - "last_affected": "2.3.5" - }, - { - "introduced": "2.3.6" - }, - { - "last_affected": "2.3.6" - }, - { - "introduced": "2.4" - }, - { - "last_affected": "2.4" - }, - { - "introduced": "2.4.1" - }, - { - "last_affected": "2.4.1" - }, - { - "introduced": "2.4.2" - }, - { - "last_affected": "2.4.2" - }, - { - "introduced": "2.4.3" - }, - { - "last_affected": "2.4.3" - }, - { - "introduced": "2.4.4" - }, - { - "last_affected": "2.4.4" - }, - { - "introduced": "2.4.5" - }, - { - "last_affected": "2.4.5" - }, - { - "introduced": "2.4.6" - }, - { - "last_affected": "2.4.6" - }, - { - "introduced": "2.4.7" - }, - { - "last_affected": "2.4.7" - }, - { - "introduced": "2.4.8" - }, - { - "last_affected": "2.4.8" - }, - { - "introduced": "2.4.9" - }, - { - "last_affected": "2.4.9" - }, - { - "introduced": "2.4.10" - }, - { - "last_affected": "2.4.10" - }, - { - "introduced": "2.4.11" - }, - { - "last_affected": "2.4.11" - }, - { - "introduced": "2.4.12" - }, - { - "last_affected": "2.4.12" - }, - { - "introduced": "2.5" - }, - { - "last_affected": "2.5" - }, - { - "introduced": "2.5.1" - }, - { - "last_affected": "2.5.1" - }, - { - "introduced": "2.5.2" - }, - { - "last_affected": "2.5.2" - }, - { - "introduced": "2.5.3" - }, - { - "last_affected": "2.5.3" - }, - { - "introduced": "2.5.4" - }, - { - "last_affected": "2.5.4" - }, - { - "introduced": "2.5.5" - }, - { - "last_affected": "2.5.5" - }, - { - "introduced": "2.5.6" - }, - { - "last_affected": "2.5.6" - }, - { - "introduced": "2.5.7" - }, - { - "last_affected": "2.5.7" - }, - { - "introduced": "2.5.8" - }, - { - "last_affected": "2.5.8" - }, - { - "introduced": "2.5.9" - }, - { - "last_affected": "2.5.9" - }, - { - "introduced": "2.6" - }, - { - "last_affected": "2.6" - }, - { - "introduced": "2.6.1" - }, - { - "last_affected": "2.6.1" - }, - { - "introduced": "2.6.2" - }, - { - "last_affected": "2.6.2" - }, - { - "introduced": "2.6.3" - }, - { - "last_affected": "2.6.3" - }, - { - "introduced": "2.6.4" - }, - { - "last_affected": "2.6.4" - }, - { - "introduced": "2.6.5" - }, - { - "last_affected": "2.6.5" - }, - { - "introduced": "2.6.6" - }, - { - "last_affected": "2.6.6" - }, - { - "introduced": "2.7" - }, - { - "last_affected": "2.7" - }, - { - "introduced": "2.7.1" - }, - { - "last_affected": "2.7.1" - }, - { - "introduced": "2.7.2" - }, - { - "last_affected": "2.7.2" - }, - { - "introduced": "2.7.3" - }, - { - "last_affected": "2.7.3" - }, - { - "introduced": "2.7.4" - }, - { - "last_affected": "2.7.4" - }, - { - "introduced": "2.8" - }, - { - "last_affected": "2.8" - }, - { - "introduced": "2.8-dev" - }, - { - "last_affected": "2.8-dev" - }, - { - "introduced": "2.8.1" - }, - { - "last_affected": "2.8.1" - }, - { - "introduced": "2.8.2" - }, - { - "last_affected": "2.8.2" - }, - { - "introduced": "2.8.3" - }, - { - "last_affected": "2.8.3" - }, - { - "introduced": "2.8.4" - }, - { - "last_affected": "2.8.4" + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.0:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.0" + }, + { + "last_affected": "2.0" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.0.1:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.0.1" + }, + { + "last_affected": "2.0.1" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.0.2:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.0.2" + }, + { + "last_affected": "2.0.2" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.0.3:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.0.3" + }, + { + "last_affected": "2.0.3" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.0.4:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.0.4" + }, + { + "last_affected": "2.0.4" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.0.5:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.0.5" + }, + { + "last_affected": "2.0.5" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.0.6:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.0.6" + }, + { + "last_affected": "2.0.6" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.0.7:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.0.7" + }, + { + "last_affected": "2.0.7" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.1:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.1" + }, + { + "last_affected": "2.1" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.1.1:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.1.1" + }, + { + "last_affected": "2.1.1" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.1.2:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.1.2" + }, + { + "last_affected": "2.1.2" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.1.3:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.1.3" + }, + { + "last_affected": "2.1.3" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.1.4:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.1.4" + }, + { + "last_affected": "2.1.4" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.1.5:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.1.5" + }, + { + "last_affected": "2.1.5" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.1.6:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.1.6" + }, + { + "last_affected": "2.1.6" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.1.7:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.1.7" + }, + { + "last_affected": "2.1.7" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.1.8:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.1.8" + }, + { + "last_affected": "2.1.8" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2" + }, + { + "last_affected": "2.2" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.1:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.1" + }, + { + "last_affected": "2.2.1" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.2:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.2" + }, + { + "last_affected": "2.2.2" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.3:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.3" + }, + { + "last_affected": "2.2.3" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.4:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.4" + }, + { + "last_affected": "2.2.4" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.5:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.5" + }, + { + "last_affected": "2.2.5" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.6:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.6" + }, + { + "last_affected": "2.2.6" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.7:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.7" + }, + { + "last_affected": "2.2.7" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.8:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.8" + }, + { + "last_affected": "2.2.8" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.9:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.9" + }, + { + "last_affected": "2.2.9" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.10:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.10" + }, + { + "last_affected": "2.2.10" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.11:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.11" + }, + { + "last_affected": "2.2.11" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.12:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.12" + }, + { + "last_affected": "2.2.12" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.13:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.13" + }, + { + "last_affected": "2.2.13" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.14:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.14" + }, + { + "last_affected": "2.2.14" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.15:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.15" + }, + { + "last_affected": "2.2.15" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.2.16:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.2.16" + }, + { + "last_affected": "2.2.16" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.3:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.3" + }, + { + "last_affected": "2.3" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.3.1:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.3.1" + }, + { + "last_affected": "2.3.1" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.3.2:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.3.2" + }, + { + "last_affected": "2.3.2" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.3.3:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.3.3" + }, + { + "last_affected": "2.3.3" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.3.4:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.3.4" + }, + { + "last_affected": "2.3.4" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.3.5:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.3.5" + }, + { + "last_affected": "2.3.5" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.3.6:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.3.6" + }, + { + "last_affected": "2.3.6" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4" + }, + { + "last_affected": "2.4" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.1:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.1" + }, + { + "last_affected": "2.4.1" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.2:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.2" + }, + { + "last_affected": "2.4.2" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.3:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.3" + }, + { + "last_affected": "2.4.3" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.4:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.4" + }, + { + "last_affected": "2.4.4" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.5:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.5" + }, + { + "last_affected": "2.4.5" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.6:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.6" + }, + { + "last_affected": "2.4.6" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.7:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.7" + }, + { + "last_affected": "2.4.7" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.8:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.8" + }, + { + "last_affected": "2.4.8" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.9:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.9" + }, + { + "last_affected": "2.4.9" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.10:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.10" + }, + { + "last_affected": "2.4.10" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.11:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.11" + }, + { + "last_affected": "2.4.11" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.4.12:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.4.12" + }, + { + "last_affected": "2.4.12" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.5:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.5" + }, + { + "last_affected": "2.5" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.5.1:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.5.1" + }, + { + "last_affected": "2.5.1" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.5.2:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.5.2" + }, + { + "last_affected": "2.5.2" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.5.3:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.5.3" + }, + { + "last_affected": "2.5.3" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.5.4:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.5.4" + }, + { + "last_affected": "2.5.4" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.5.5:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.5.5" + }, + { + "last_affected": "2.5.5" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.5.6:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.5.6" + }, + { + "last_affected": "2.5.6" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.5.7:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.5.7" + }, + { + "last_affected": "2.5.7" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.5.8:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.5.8" + }, + { + "last_affected": "2.5.8" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.5.9:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.5.9" + }, + { + "last_affected": "2.5.9" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.6:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.6" + }, + { + "last_affected": "2.6" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.6.1:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.6.1" + }, + { + "last_affected": "2.6.1" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.6.2:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.6.2" + }, + { + "last_affected": "2.6.2" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.6.3:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.6.3" + }, + { + "last_affected": "2.6.3" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.6.4:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.6.4" + }, + { + "last_affected": "2.6.4" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.6.5:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.6.5" + }, + { + "last_affected": "2.6.5" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.6.6:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.6.6" + }, + { + "last_affected": "2.6.6" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.7:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.7" + }, + { + "last_affected": "2.7" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.7.1:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.7.1" + }, + { + "last_affected": "2.7.1" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.7.2:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.7.2" + }, + { + "last_affected": "2.7.2" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.7.3:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.7.3" + }, + { + "last_affected": "2.7.3" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.7.4:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.7.4" + }, + { + "last_affected": "2.7.4" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.8:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.8" + }, + { + "last_affected": "2.8" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.8:dev:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.8-dev" + }, + { + "last_affected": "2.8-dev" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.8.1:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.8.1" + }, + { + "last_affected": "2.8.1" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.8.2:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.8.2" + }, + { + "last_affected": "2.8.2" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.8.3:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.8.3" + }, + { + "last_affected": "2.8.3" + } + ], + "source": "CPE_STRING" + }, + { + "cpe": "cpe:2.3:a:ffmpeg:ffmpeg:2.8.4:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "2.8.4" + }, + { + "last_affected": "2.8.4" + } + ], + "source": "CPE_STRING" } - ], - "source": "CPE_STRING" + ] }, "events": [ { @@ -3386,16 +3883,20 @@ "ranges": [ { "database_specific": { - "cpe": "cpe:2.3:a:libdwarf_project:libdwarf:*:*:*:*:*:*:*:*", "extracted_events": [ { - "introduced": "0.1.0" - }, - { - "fixed": "0.9.2" + "cpe": "cpe:2.3:a:libdwarf_project:libdwarf:*:*:*:*:*:*:*:*", + "range": [ + { + "introduced": "0.1.0" + }, + { + "fixed": "0.9.2" + } + ], + "source": "CPE_RANGE" } - ], - "source": "CPE_RANGE" + ] }, "events": [ { diff --git a/vulnfeeds/conversion/versions.go b/vulnfeeds/conversion/versions.go index c4387b3723d..dbfc80a830a 100644 --- a/vulnfeeds/conversion/versions.go +++ b/vulnfeeds/conversion/versions.go @@ -424,10 +424,10 @@ func repo(u string) (string, error) { } // Returns the commit ID from supported links. -func Commit(u string) (string, error) { +func Commit(u string) (string, string, models.VersionSource, error) { parsedURL, err := url.Parse(u) if err != nil { - return "", err + return "", "", models.VersionSourceNone, err } gitSHA1Regex := regexp.MustCompile("^[0-9a-f]{7,40}") @@ -440,14 +440,14 @@ func Commit(u string) (string, error) { if strings.HasPrefix(parsedURL.Path, "/cgit") && strings.HasSuffix(parsedURL.Path, "commit/") && strings.HasPrefix(parsedURL.RawQuery, "id=") { - return strings.Split(parsedURL.RawQuery, "=")[1], nil + return strings.Split(parsedURL.RawQuery, "=")[1], "", models.VersionSourceRefsCommit, nil } // Canonicalized git.kernel.org URLs lose /cgit in the path... if parsedURL.Hostname() == "git.kernel.org" && strings.HasSuffix(parsedURL.Path, "commit/") && strings.HasPrefix(parsedURL.RawQuery, "id=") { - return strings.Split(parsedURL.RawQuery, "=")[1], nil + return strings.Split(parsedURL.RawQuery, "=")[1], "", models.VersionSourceRefsCommit, nil } // GitWeb cgi-bin URLs are structured another way, e.g. @@ -460,14 +460,14 @@ func Commit(u string) (string, error) { continue } - return strings.Split(param, "=")[1], nil + return strings.Split(param, "=")[1], "", models.VersionSourceRefsCommit, nil } } // FFMpeg's GitWeb seems to be it's own unique snowflake, e.g. // https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/c94875471e3ba3dc396c6919ff3ec9b14539cd71 if strings.HasPrefix(parsedURL.Path, "/gitweb/") && len(strings.Split(parsedURL.Path, "/")) == 5 { - return strings.Split(parsedURL.Path, "/")[4], nil + return strings.Split(parsedURL.Path, "/")[4], "", models.VersionSourceRefsCommit, nil } // GitHub and GitLab commit URLs are structured one way, e.g. @@ -478,7 +478,7 @@ func Commit(u string) (string, error) { parsedURL.Path = strings.TrimSuffix(parsedURL.Path, "/") directory, possibleCommitHash := path.Split(parsedURL.Path) if strings.HasSuffix(directory, "commit/") && gitSHA1Regex.MatchString(possibleCommitHash) { - return strings.TrimSuffix(possibleCommitHash, ".patch"), nil + return strings.TrimSuffix(possibleCommitHash, ".patch"), "", models.VersionSourceRefsCommit, nil } // and Bitbucket.org commit URLs are similar yet slightly different: @@ -490,7 +490,7 @@ func Commit(u string) (string, error) { parsedURL.Path = strings.TrimSuffix(parsedURL.Path, "/") directory, possibleCommitHash := path.Split(parsedURL.Path) if strings.HasSuffix(directory, "commits/") && gitSHA1Regex.MatchString(possibleCommitHash) { - return possibleCommitHash, nil + return possibleCommitHash, "", models.VersionSourceRefsCommit, nil } } @@ -499,42 +499,43 @@ func Commit(u string) (string, error) { // Support for resolving a Github tag to a commit hash // example: https://github.com/redis/redis/releases/tag/6.2.17 if parsedURL.Host == "github.com" { - possibleCommitHash, err := resolveGitTag(parsedURL, u, gitSHA1Regex) + possibleCommitHash, originalTag, err := resolveGitTag(parsedURL, u, gitSHA1Regex) if possibleCommitHash != "" && err == nil { - return possibleCommitHash, nil + return possibleCommitHash, originalTag, models.VersionSourceRefsTag, nil } } // If we get to here, we've encountered an unsupported URL. - return "", fmt.Errorf("Commit(): unsupported URL: %s", u) + return "", "", models.VersionSourceNone, fmt.Errorf("Commit(): unsupported URL: %s", u) } -func resolveGitTag(parsedURL *url.URL, u string, gitSHA1Regex *regexp.Regexp) (string, error) { +func resolveGitTag(parsedURL *url.URL, u string, gitSHA1Regex *regexp.Regexp) (string, string, error) { directory, tag := path.Split(parsedURL.Path) if !strings.HasSuffix(directory, "tag/") { - return "", errors.New("no tag found") + return "", "", errors.New("no tag found") } + originalTag := tag tag, err := git.NormalizeVersion(tag) if err != nil { - return "", err + return "", "", err } maybeRepoURL, err := Repo(u) if err != nil { - return "", err + return "", "", err } normalizedTags, err := git.NormalizeRepoTags(maybeRepoURL, nil) if err != nil { - return "", err + return "", "", err } for t, nTag := range normalizedTags { if tag == t && gitSHA1Regex.MatchString(nTag.Commit) { - return nTag.Commit, nil + return nTag.Commit, originalTag, nil } } - return "", errors.New("no tag found") + return "", "", errors.New("no tag found") } // For URLs referencing commits in supported Git repository hosts, return a cloneable AffectedCommit. @@ -561,32 +562,34 @@ func ExtractCommitsFromRefs(references []models.Reference, httpClient *http.Clie // For URLs referencing commits in supported Git repository hosts, return a cloneable AffectedCommit. func extractGitAffectedCommit(link string, commitType models.CommitType, httpClient *http.Client, cache git.RepoTagsCache) (models.AffectedCommit, error) { var ac models.AffectedCommit - c, r, err := ExtractGitCommit(link, httpClient, 0, cache) + c, r, tag, source, err := ExtractGitCommit(link, httpClient, 0, cache) if err != nil { return ac, err } ac.SetRepo(r) + ac.Source = source + ac.OriginalTag = tag models.SetCommitByType(&ac, commitType, c) return ac, nil } -func ExtractGitCommit(link string, httpClient *http.Client, depth int, cache git.RepoTagsCache) (string, string, error) { +func ExtractGitCommit(link string, httpClient *http.Client, depth int, cache git.RepoTagsCache) (string, string, string, models.VersionSource, error) { if depth > 10 { - return "", "", fmt.Errorf("max recursion depth exceeded for %s", link) + return "", "", "", models.VersionSourceNone, fmt.Errorf("max recursion depth exceeded for %s", link) } var commit string r, err := Repo(link) if err != nil { - return "", "", err + return "", "", "", models.VersionSourceNone, err } - c, err := Commit(link) + c, tag, source, err := Commit(link) if err != nil { - return "", "", err + return "", "", "", models.VersionSourceNone, err } commit = c @@ -594,7 +597,7 @@ func ExtractGitCommit(link string, httpClient *http.Client, depth int, cache git // If URL doesn't validate, treat it as linkrot. possiblyDifferentLink, err := git.FindCanonicalLink(link, httpClient, cache) if err != nil { - return "", "", err + return "", "", "", models.VersionSourceNone, err } // restart the entire extraction process when the URL changes (i.e. handle a @@ -604,7 +607,7 @@ func ExtractGitCommit(link string, httpClient *http.Client, depth int, cache git return ExtractGitCommit(possiblyDifferentLink, httpClient, depth+1, cache) } - return commit, r, nil + return commit, r, tag, source, nil } func HasVersion(validVersions []string, version string) bool { @@ -1247,7 +1250,7 @@ func ReposFromReferences(cache *VPRepoCache, vp *VendorProduct, refs []models.Re continue } // If the reference is a commit URL, the repo is inherently useful (but only if the repo still ultimately works). - _, err = Commit(ref.URL) + _, _, _, err = Commit(ref.URL) // Check if it was previously found to be bad: if repoTagsCache != nil && repoTagsCache.IsInvalid(repo) { continue diff --git a/vulnfeeds/conversion/versions_test.go b/vulnfeeds/conversion/versions_test.go index f1906a0fa8f..0907088d1ed 100644 --- a/vulnfeeds/conversion/versions_test.go +++ b/vulnfeeds/conversion/versions_test.go @@ -512,8 +512,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://github.com/google/osv/commit/cd4e934d0527e5010e373e7fed54ef5daefba2f5", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://github.com/google/osv.dev", - Fixed: "cd4e934d0527e5010e373e7fed54ef5daefba2f5", + Repo: "https://github.com/google/osv.dev", + Fixed: "cd4e934d0527e5010e373e7fed54ef5daefba2f5", + Source: models.VersionSourceRefsCommit, }, }, { @@ -527,8 +528,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://github.com/pimcore/customer-data-framework/commit/e3f333391582d9309115e6b94e875367d0ea7163.patch", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://github.com/pimcore/customer-data-framework", - Fixed: "e3f333391582d9309115e6b94e875367d0ea7163", + Repo: "https://github.com/pimcore/customer-data-framework", + Fixed: "e3f333391582d9309115e6b94e875367d0ea7163", + Source: models.VersionSourceRefsCommit, }, }, { @@ -542,8 +544,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://gitlab.freedesktop.org/virgl/virglrenderer/-/commit/b05bb61f454eeb8a85164c8a31510aeb9d79129c", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://gitlab.freedesktop.org/virgl/virglrenderer", - Fixed: "b05bb61f454eeb8a85164c8a31510aeb9d79129c", + Repo: "https://gitlab.freedesktop.org/virgl/virglrenderer", + Fixed: "b05bb61f454eeb8a85164c8a31510aeb9d79129c", + Source: models.VersionSourceRefsCommit, }, }, { @@ -551,8 +554,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://gitlab.com/muttmua/mutt/-/commit/452ee330e094bfc7c9a68555e5152b1826534555.patch", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://gitlab.com/muttmua/mutt", - Fixed: "452ee330e094bfc7c9a68555e5152b1826534555", + Repo: "https://gitlab.com/muttmua/mutt", + Fixed: "452ee330e094bfc7c9a68555e5152b1826534555", + Source: models.VersionSourceRefsCommit, }, }, { @@ -560,8 +564,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://gitlab.com/mayan-edms/mayan-edms/commit/9ebe80595afe4fdd1e2c74358d6a9421f4ce130e", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://gitlab.com/mayan-edms/mayan-edms", - Fixed: "9ebe80595afe4fdd1e2c74358d6a9421f4ce130e", + Repo: "https://gitlab.com/mayan-edms/mayan-edms", + Fixed: "9ebe80595afe4fdd1e2c74358d6a9421f4ce130e", + Source: models.VersionSourceRefsCommit, }, }, { @@ -569,8 +574,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://bitbucket.org/openpyxl/openpyxl/commits/3b4905f428e1", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://bitbucket.org/openpyxl/openpyxl", - Fixed: "3b4905f428e1", + Repo: "https://bitbucket.org/openpyxl/openpyxl", + Fixed: "3b4905f428e1", + Source: models.VersionSourceRefsCommit, }, }, { @@ -578,8 +584,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://bitbucket.org/utmandrew/pcrs/commits/5f18bcb/", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://bitbucket.org/utmandrew/pcrs", - Fixed: "5f18bcb", + Repo: "https://bitbucket.org/utmandrew/pcrs", + Fixed: "5f18bcb", + Source: models.VersionSourceRefsCommit, }, }, { @@ -587,8 +594,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=faa4c92debe45412bfcf8a44f26e827800bb24be", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://git.dpkg.org/cgit/dpkg/dpkg.git", - Fixed: "faa4c92debe45412bfcf8a44f26e827800bb24be", + Repo: "https://git.dpkg.org/cgit/dpkg/dpkg.git", + Fixed: "faa4c92debe45412bfcf8a44f26e827800bb24be", + Source: models.VersionSourceRefsCommit, }, }, { @@ -599,8 +607,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libksba.git&a=commit&h=f61a5ea4e0f6a80fd4b28ef0174bee77793cf070", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "git://git.gnupg.org/libksba.git", - Fixed: "f61a5ea4e0f6a80fd4b28ef0174bee77793cf070", + Repo: "git://git.gnupg.org/libksba.git", + Fixed: "f61a5ea4e0f6a80fd4b28ef0174bee77793cf070", + Source: models.VersionSourceRefsCommit, }, }, { @@ -615,8 +624,10 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://github.com/google/osv.dev/releases/tag/v0.0.14", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://github.com/google/osv.dev", - Fixed: "8de7697b3b8a73e79a73ec34f17ef0fa842cfbb2", + Repo: "https://github.com/google/osv.dev", + Fixed: "8de7697b3b8a73e79a73ec34f17ef0fa842cfbb2", + Source: models.VersionSourceRefsTag, + OriginalTag: "v0.0.14", }, expectFailure: false, }, @@ -632,8 +643,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ee1fee900537b5d9560e9f937402de5ddc8412f3", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git", - Fixed: "ee1fee900537b5d9560e9f937402de5ddc8412f3", + Repo: "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git", + Fixed: "ee1fee900537b5d9560e9f937402de5ddc8412f3", + Source: models.VersionSourceRefsCommit, }, skipOnCloudBuild: true, // observing indications of IP denylisting as at 2025-02-13 }, @@ -642,8 +654,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/c94875471e3ba3dc396c6919ff3ec9b14539cd71", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://git.ffmpeg.org/ffmpeg.git", - Fixed: "c94875471e3ba3dc396c6919ff3ec9b14539cd71", + Repo: "https://git.ffmpeg.org/ffmpeg.git", + Fixed: "c94875471e3ba3dc396c6919ff3ec9b14539cd71", + Source: models.VersionSourceRefsCommit, }, }, { @@ -651,8 +664,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://github.com/uWebSockets/uWebSockets/commit/37deefd01f0875e133ea967122e3a5e421b8fcd9", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://github.com/unetworking/uwebsockets", - Fixed: "37deefd01f0875e133ea967122e3a5e421b8fcd9", + Repo: "https://github.com/unetworking/uwebsockets", + Fixed: "37deefd01f0875e133ea967122e3a5e421b8fcd9", + Source: models.VersionSourceRefsCommit, }, }, { @@ -660,8 +674,9 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://github.com/eggjs/extend2/commit/aa332a59116c8398976434b57ea477c6823054f8", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://github.com/eggjs/extend2", - Fixed: "aa332a59116c8398976434b57ea477c6823054f8", + Repo: "https://github.com/eggjs/extend2", + Fixed: "aa332a59116c8398976434b57ea477c6823054f8", + Source: models.VersionSourceRefsCommit, }, }, { @@ -676,8 +691,10 @@ func TestExtractGitCommit(t *testing.T) { inputLink: "https://github.com/redis/redis/releases/tag/6.2.17", inputCommitType: models.Fixed, expectedAffectedCommit: models.AffectedCommit{ - Repo: "https://github.com/redis/redis", - Fixed: "441001a4e5e37a7a450c0929d2a94ba489941874", + Repo: "https://github.com/redis/redis", + Fixed: "441001a4e5e37a7a450c0929d2a94ba489941874", + Source: models.VersionSourceRefsTag, + OriginalTag: "6.2.17", }, expectFailure: false, }, @@ -1128,6 +1145,8 @@ func TestCommit(t *testing.T) { name string args args want string + wantTag string + wantSource models.VersionSource wantErr bool disableExpiryDate time.Time // If test needs to be disabled due to known outage. }{ @@ -1136,40 +1155,45 @@ func TestCommit(t *testing.T) { args: args{ u: "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ee1fee900537b5d9560e9f937402de5ddc8412f3", }, - want: "ee1fee900537b5d9560e9f937402de5ddc8412f3", - wantErr: false, + want: "ee1fee900537b5d9560e9f937402de5ddc8412f3", + wantSource: models.VersionSourceRefsCommit, + wantErr: false, }, { name: "an unusual and technically valid GitHub commit URL based on a tag (with ancestry)", args: args{ u: "https://github.com/curl/curl/commit/curl-7_50_2~32", }, - want: "", // Ideally it would be 7700fcba64bf5806de28f6c1c7da3b4f0b38567d but this isn't `git rev-parse` - wantErr: true, + want: "", // Ideally it would be 7700fcba64bf5806de28f6c1c7da3b4f0b38567d but this isn't `git rev-parse` + wantSource: models.VersionSourceNone, + wantErr: true, }, { name: "Valid GitHub commit URL", args: args{ u: "https://github.com/MariaDB/server/commit/b1351c15946349f9daa7e5297fb2ac6f3139e4a", }, - want: "b1351c15946349f9daa7e5297fb2ac6f3139e4a", - wantErr: false, + want: "b1351c15946349f9daa7e5297fb2ac6f3139e4a", + wantSource: models.VersionSourceRefsCommit, + wantErr: false, }, { name: "Valid FreeDesktop GitLab commit URL", args: args{ u: "https://gitlab.freedesktop.org/virgl/virglrenderer/-/commit/b05bb61f454eeb8a85164c8a31510aeb9d79129", }, - want: "b05bb61f454eeb8a85164c8a31510aeb9d79129", - wantErr: false, + want: "b05bb61f454eeb8a85164c8a31510aeb9d79129", + wantSource: models.VersionSourceRefsCommit, + wantErr: false, }, { name: "Valid GitLab commit URL with a shorter hash", args: args{ u: "https://gitlab.com/qemu-project/qemu/-/commit/4367a20cc", }, - want: "4367a20cc", - wantErr: false, + want: "4367a20cc", + wantSource: models.VersionSourceRefsCommit, + wantErr: false, }, } for _, tt := range tests { @@ -1177,7 +1201,7 @@ func TestCommit(t *testing.T) { if time.Now().Before(tt.disableExpiryDate) { t.Skipf("test %q has been skipped due to known outage and will be reenabled on %s.", tt.name, tt.disableExpiryDate) } - got, err := Commit(tt.args.u) + got, gotTag, gotSource, err := Commit(tt.args.u) if (err != nil) != tt.wantErr { t.Errorf("Commit() error = %v, wantErr %v", err, tt.wantErr) return @@ -1185,6 +1209,12 @@ func TestCommit(t *testing.T) { if got != tt.want { t.Errorf("Commit() = %v, want %v", got, tt.want) } + if gotSource != tt.wantSource { + t.Errorf("Commit() source = %v, want %v", gotSource, tt.wantSource) + } + if gotTag != tt.wantTag { + t.Errorf("Commit() tag = %v, want %v", gotTag, tt.wantTag) + } }) } } diff --git a/vulnfeeds/models/metrics.go b/vulnfeeds/models/metrics.go index d1334f20bcd..f84ebe0bc59 100644 --- a/vulnfeeds/models/metrics.go +++ b/vulnfeeds/models/metrics.go @@ -115,6 +115,8 @@ const ( VersionSourceDescription VersionSource = "DESCRIPTION" VersionSourceText VersionSource = "TEXT_EXTRACTION" VersionSourceRefs VersionSource = "REFERENCES" + VersionSourceRefsCommit VersionSource = "REFERENCES_COMMIT" + VersionSourceRefsTag VersionSource = "REFERENCES_TAG" ) func DetermineOutcome(metrics *ConversionMetrics) { diff --git a/vulnfeeds/models/types.go b/vulnfeeds/models/types.go index 58cfede8682..74f41daaff1 100644 --- a/vulnfeeds/models/types.go +++ b/vulnfeeds/models/types.go @@ -10,11 +10,13 @@ import ( ) type AffectedCommit struct { - Repo string `json:"repo,omitempty" yaml:"repo,omitempty"` - Introduced string `json:"introduced,omitempty" yaml:"introduced,omitempty"` - Fixed string `json:"fixed,omitempty" yaml:"fixed,omitempty"` - Limit string `json:"limit,omitempty" yaml:"limit,omitempty"` - LastAffected string `json:"last_affected,omitempty" yaml:"last_affected,omitempty"` + Repo string `json:"repo,omitempty" yaml:"repo,omitempty"` + Introduced string `json:"introduced,omitempty" yaml:"introduced,omitempty"` + Fixed string `json:"fixed,omitempty" yaml:"fixed,omitempty"` + Limit string `json:"limit,omitempty" yaml:"limit,omitempty"` + LastAffected string `json:"last_affected,omitempty" yaml:"last_affected,omitempty"` + Source VersionSource `json:"-" yaml:"-"` + OriginalTag string `json:"-" yaml:"-"` } // SetCommitByType sets the appropriate commit field on an AffectedCommit based on the CommitType. @@ -37,9 +39,10 @@ type RangeWithMetadata struct { } type Metadata struct { - CPE string - Source VersionSource - Versions []string + CPE string + Source VersionSource + Versions []string + OriginalTag string } func (ac *AffectedCommit) SetRepo(repo string) {