diff --git a/vulnfeeds/cmd/combine-to-osv/main.go b/vulnfeeds/cmd/combine-to-osv/main.go index 9bfd50f1c21..6ef18fa246e 100644 --- a/vulnfeeds/cmd/combine-to-osv/main.go +++ b/vulnfeeds/cmd/combine-to-osv/main.go @@ -607,12 +607,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() @@ -627,7 +656,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 { @@ -635,9 +668,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 @@ -688,6 +721,29 @@ 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 + } + } + if strategyVal, ok := groupFields["strategy"]; ok { + if strategyVal.GetStringValue() == "CPEApplicability" { + 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 865c9f46fe9..04646cd5a41 100644 --- a/vulnfeeds/conversion/common.go +++ b/vulnfeeds/conversion/common.go @@ -293,16 +293,7 @@ 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(), - } - if vr.Metadata.CPE != "" { - dbSpecificMap["cpe"] = vr.Metadata.CPE - } - if string(vr.Metadata.Source) != "" { - dbSpecificMap["source"] = string(vr.Metadata.Source) - } - databaseSpecific, err := utility.NewStructpbFromMap(dbSpecificMap) + databaseSpecific, err := buildRangeDatabaseSpecific(vr) if err != nil { metrics.AddNotef("failed to make database specific: %v", err) } else { @@ -324,6 +315,29 @@ func GitVersionsToCommits(versionRanges []models.RangeWithMetadata, repos []stri return newVersionRanges, unresolvedRanges, successfulRepos } +func buildRangeDatabaseSpecific(vr models.RangeWithMetadata) (*structpb.Struct, error) { + extractedEventGroup := map[string]any{ + "range": vr.Range.GetEvents(), + } + if vr.Metadata.CPE != "" { + extractedEventGroup["cpe"] = vr.Metadata.CPE + } + if string(vr.Metadata.Source) != "" { + extractedEventGroup["source"] = string(vr.Metadata.Source) + } + if vr.Metadata.Strategy != "" { + extractedEventGroup["strategy"] = vr.Metadata.Strategy + } + if vr.Metadata.OriginalTag != "" { + extractedEventGroup["original_tag"] = vr.Metadata.OriginalTag + } + dbSpecificMap := map[string]any{ + "extracted_events": []any{extractedEventGroup}, + } + + return utility.NewStructpbFromMap(dbSpecificMap) +} + // BuildVersionRange is a helper function that adds 'introduced', 'fixed', or 'last_affected' // events to an OSV version range. If 'intro' is empty, it defaults to "0". func BuildVersionRange(intro string, lastAff string, fixed string) *osvschema.Range { @@ -555,7 +569,9 @@ func CreateUnresolvedRanges(unresolvedRanges []models.RangeWithMetadata) *struct type key struct { Source string + Strategy string VendorProduct string + OriginalTag string } rangesByKey := make(map[key][]models.RangeWithMetadata) @@ -570,7 +586,12 @@ 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), + Strategy: ur.Metadata.Strategy, + VendorProduct: vendorProduct, + OriginalTag: ur.Metadata.OriginalTag, + } if _, ok := rangesByKey[k]; !ok { keys = append(keys, k) } @@ -581,8 +602,14 @@ func CreateUnresolvedRanges(unresolvedRanges []models.RangeWithMetadata) *struct if a.Source != b.Source { return strings.Compare(a.Source, b.Source) } + if a.Strategy != b.Strategy { + return strings.Compare(a.Strategy, b.Strategy) + } + 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)) @@ -623,14 +650,24 @@ 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.Strategy != "" { + extractedEventGroup["strategy"] = k.Strategy + } + if k.OriginalTag != "" { + extractedEventGroup["original_tag"] = k.OriginalTag + } + + unresolvedRangesMap["extracted_events"] = []any{extractedEventGroup} listElements = append(listElements, unresolvedRangesMap) } @@ -807,6 +844,13 @@ func ProcessRanges(ranges []models.RangeWithMetadata, repos []string, metrics *m if repo != "" { vr.Range.Repo = repo vr.Range.Type = osvschema.Range_GIT + if len(vr.Range.GetEvents()) > 0 && vr.Range.GetDatabaseSpecific() == nil { + if databaseSpecific, err := buildRangeDatabaseSpecific(vr); err != nil { + metrics.AddNotef("failed to make database specific: %v", err) + } else { + vr.Range.DatabaseSpecific = databaseSpecific + } + } resolvedRanges = append(resolvedRanges, vr) successfulRepos = append(successfulRepos, repo) } else { diff --git a/vulnfeeds/conversion/common_test.go b/vulnfeeds/conversion/common_test.go index e6da1344ff4..b5c702881d6 100644 --- a/vulnfeeds/conversion/common_test.go +++ b/vulnfeeds/conversion/common_test.go @@ -392,7 +392,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:*:*:*:*:*:*:*:*"), @@ -406,7 +405,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"), + }, + }, + }, + }, + }, + }), }, }, }, @@ -424,7 +436,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:*:*:*:*:*:*:*:*"), @@ -438,7 +449,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 de1ea01eab7..9d0222c6372 100755 --- a/vulnfeeds/conversion/cve5/__snapshots__/converter_test.snap +++ b/vulnfeeds/conversion/cve5/__snapshots__/converter_test.snap @@ -2304,13 +2304,18 @@ { "extracted_events": [ { - "introduced": "11 and 12" - }, - { - "last_affected": "11 and 12" + "range": [ + { + "introduced": "11 and 12" + }, + { + "last_affected": "11 and 12" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" } - ], - "source": "AFFECTED_FIELD" + ] } ] }, @@ -2348,13 +2353,18 @@ { "extracted_events": [ { - "introduced": "7.61.1" - }, - { - "last_affected": "7.61.1" + "range": [ + { + "introduced": "7.61.1" + }, + { + "last_affected": "7.61.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" } - ], - "source": "AFFECTED_FIELD" + ] } ] }, @@ -2433,13 +2443,18 @@ { "extracted_events": [ { - "introduced": "0.1.0" - }, - { - "last_affected": "0.1.0" + "range": [ + { + "introduced": "0.1.0" + }, + { + "last_affected": "0.1.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" } - ], - "source": "AFFECTED_FIELD" + ] } ] }, @@ -2496,13 +2511,18 @@ "database_specific": { "extracted_events": [ { - "introduced": "4.x" - }, - { - "last_affected": "4.x" + "range": [ + { + "introduced": "4.x" + }, + { + "last_affected": "4.x" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -2573,25 +2593,42 @@ "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", + "strategy": "StringRangeExpression" + }, + { + "range": [ + { + "introduced": "1.19.0" + }, + { + "fixed": "1.20.3" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StringRangeExpression" + }, + { + "range": [ + { + "introduced": "1.21.0" + }, + { + "fixed": "1.23.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StringRangeExpression" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -2674,19 +2711,42 @@ "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", + "strategy": "StandardRange" + }, + { + "range": [ + { + "introduced": "0" + }, + { + "fixed": "5.29.5" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandardRange" + }, + { + "range": [ + { + "introduced": "0" + }, + { + "fixed": "6.31.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandardRange" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -2756,13 +2816,18 @@ "database_specific": { "extracted_events": [ { - "introduced": "0" - }, - { - "fixed": "2.0.0-next.193" + "range": [ + { + "introduced": "0" + }, + { + "fixed": "2.0.0-next.193" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StringRangeExpression" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -2828,761 +2893,1335 @@ "database_specific": { "extracted_events": [ { - "introduced": "8.9.0" - }, + "range": [ + { + "introduced": "8.9.0" + }, + { + "last_affected": "8.9.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.8.0" + }, + { + "last_affected": "8.8.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.7.1" + }, + { + "last_affected": "8.7.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.7.0" + }, + { + "last_affected": "8.7.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.6.0" + }, + { + "last_affected": "8.6.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.5.0" + }, + { + "last_affected": "8.5.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.4.0" + }, + { + "last_affected": "8.4.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.3.0" + }, + { + "last_affected": "8.3.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.2.1" + }, + { + "last_affected": "8.2.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.2.0" + }, + { + "last_affected": "8.2.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.1.2" + }, + { + "last_affected": "8.1.2" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.1.1" + }, + { + "last_affected": "8.1.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.1.0" + }, + { + "last_affected": "8.1.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.0.1" + }, + { + "last_affected": "8.0.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "8.0.0" + }, + { + "last_affected": "8.0.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.88.1" + }, + { + "last_affected": "7.88.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.88.0" + }, + { + "last_affected": "7.88.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.87.0" + }, + { + "last_affected": "7.87.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.86.0" + }, + { + "last_affected": "7.86.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.85.0" + }, + { + "last_affected": "7.85.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.84.0" + }, + { + "last_affected": "7.84.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.83.1" + }, + { + "last_affected": "7.83.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.83.0" + }, + { + "last_affected": "7.83.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.82.0" + }, + { + "last_affected": "7.82.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.81.0" + }, + { + "last_affected": "7.81.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.80.0" + }, + { + "last_affected": "7.80.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.79.1" + }, + { + "last_affected": "7.79.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.79.0" + }, + { + "last_affected": "7.79.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.78.0" + }, + { + "last_affected": "7.78.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.77.0" + }, + { + "last_affected": "7.77.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.76.1" + }, + { + "last_affected": "7.76.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.76.0" + }, + { + "last_affected": "7.76.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.75.0" + }, + { + "last_affected": "7.75.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.74.0" + }, + { + "last_affected": "7.74.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.73.0" + }, + { + "last_affected": "7.73.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.72.0" + }, + { + "last_affected": "7.72.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.71.1" + }, + { + "last_affected": "7.71.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.71.0" + }, + { + "last_affected": "7.71.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.70.0" + }, + { + "last_affected": "7.70.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.69.1" + }, + { + "last_affected": "7.69.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.69.0" + }, + { + "last_affected": "7.69.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.68.0" + }, + { + "last_affected": "7.68.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.67.0" + }, + { + "last_affected": "7.67.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.66.0" + }, + { + "last_affected": "7.66.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.65.3" + }, + { + "last_affected": "7.65.3" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.65.2" + }, + { + "last_affected": "7.65.2" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.65.1" + }, + { + "last_affected": "7.65.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.65.0" + }, + { + "last_affected": "7.65.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.64.1" + }, + { + "last_affected": "7.64.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.64.0" + }, + { + "last_affected": "7.64.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.63.0" + }, + { + "last_affected": "7.63.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.62.0" + }, + { + "last_affected": "7.62.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.61.1" + }, + { + "last_affected": "7.61.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.61.0" + }, + { + "last_affected": "7.61.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.60.0" + }, + { + "last_affected": "7.60.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.59.0" + }, + { + "last_affected": "7.59.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.58.0" + }, + { + "last_affected": "7.58.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.57.0" + }, + { + "last_affected": "7.57.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.56.1" + }, + { + "last_affected": "7.56.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.56.0" + }, + { + "last_affected": "7.56.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.55.1" + }, + { + "last_affected": "7.55.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.55.0" + }, + { + "last_affected": "7.55.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.54.1" + }, + { + "last_affected": "7.54.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.54.0" + }, + { + "last_affected": "7.54.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.53.1" + }, + { + "last_affected": "7.53.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.53.0" + }, + { + "last_affected": "7.53.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.52.1" + }, + { + "last_affected": "7.52.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.52.0" + }, + { + "last_affected": "7.52.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.51.0" + }, + { + "last_affected": "7.51.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.50.3" + }, + { + "last_affected": "7.50.3" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.50.2" + }, + { + "last_affected": "7.50.2" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.50.1" + }, + { + "last_affected": "7.50.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.50.0" + }, + { + "last_affected": "7.50.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.49.1" + }, + { + "last_affected": "7.49.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.49.0" + }, + { + "last_affected": "7.49.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.48.0" + }, + { + "last_affected": "7.48.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.47.1" + }, + { + "last_affected": "7.47.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.47.0" + }, + { + "last_affected": "7.47.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.46.0" + }, + { + "last_affected": "7.46.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.45.0" + }, + { + "last_affected": "7.45.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.44.0" + }, + { + "last_affected": "7.44.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.43.0" + }, + { + "last_affected": "7.43.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.42.1" + }, + { + "last_affected": "7.42.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.42.0" + }, + { + "last_affected": "7.42.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.41.0" + }, + { + "last_affected": "7.41.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.40.0" + }, + { + "last_affected": "7.40.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.39.0" + }, + { + "last_affected": "7.39.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.38.0" + }, + { + "last_affected": "7.38.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.37.1" + }, + { + "last_affected": "7.37.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.37.0" + }, + { + "last_affected": "7.37.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.36.0" + }, + { + "last_affected": "7.36.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.35.0" + }, + { + "last_affected": "7.35.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.34.0" + }, + { + "last_affected": "7.34.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.33.0" + }, + { + "last_affected": "7.33.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "7.32.0" + }, + { + "last_affected": "7.32.0" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" + } + ] + }, + "events": [ + { + "introduced": "5040f7e94cd01decbe7ba8fdacbf489182d503dc" + }, + { + "last_affected": "70812c2f32fc5734bcbbe572b9f61c380433ad6a" + } + ], + "repo": "https://github.com/curl/curl", + "type": "GIT" + } + ], + "versions": [ + "7.32.0", + "7.33.0", + "7.34.0", + "7.35.0", + "7.36.0", + "7.37.0", + "7.37.1", + "7.38.0", + "7.39.0", + "7.40.0", + "7.41.0", + "7.42.0", + "7.42.1", + "7.43.0", + "7.44.0", + "7.45.0", + "7.46.0", + "7.47.0", + "7.47.1", + "7.48.0", + "7.49.0", + "7.49.1", + "7.50.0", + "7.50.1", + "7.50.2", + "7.50.3", + "7.51.0", + "7.52.0", + "7.52.1", + "7.53.0", + "7.53.1", + "7.54.0", + "7.54.1", + "7.55.0", + "7.55.1", + "7.56.0", + "7.56.1", + "7.57.0", + "7.58.0", + "7.59.0", + "7.60.0", + "7.61.0", + "7.61.1", + "7.62.0", + "7.63.0", + "7.64.0", + "7.64.1", + "7.65.0", + "7.65.1", + "7.65.2", + "7.65.3", + "7.66.0", + "7.67.0", + "7.68.0", + "7.69.0", + "7.69.1", + "7.70.0", + "7.71.0", + "7.71.1", + "7.72.0", + "7.73.0", + "7.74.0", + "7.75.0", + "7.76.0", + "7.76.1", + "7.77.0", + "7.78.0", + "7.79.0", + "7.79.1", + "7.80.0", + "7.81.0", + "7.82.0", + "7.83.0", + "7.83.1", + "7.84.0", + "7.85.0", + "7.86.0", + "7.87.0", + "7.88.0", + "7.88.1", + "8.0.0", + "8.0.1", + "8.1.0", + "8.1.1", + "8.1.2", + "8.2.0", + "8.2.1", + "8.3.0", + "8.4.0", + "8.5.0", + "8.6.0", + "8.7.0", + "8.7.1", + "8.8.0", + "8.9.0" + ] + } + ], + "database_specific": { + "cna_assigner": "curl", + "osv_generated_from": "unknown" + }, + "details": "libcurl's ASN1 parser code has the `GTime2str()` function, used for parsing an\nASN.1 Generalized Time field. If given an syntactically incorrect field, the\nparser might end up using -1 for the length of the *time fraction*, leading to\na `strlen()` getting performed on a pointer to a heap buffer area that is not\n(purposely) null terminated.\n\nThis flaw most likely leads to a crash, but can also lead to heap contents\ngetting returned to the application when\n[CURLINFO_CERTINFO](https://curl.se/libcurl/c/CURLINFO_CERTINFO.html) is used.", + "id": "CVE-2024-7264", + "modified": "2025-11-03T22:32:51.400Z", + "published": "2024-07-31T08:08:14.585Z", + "references": [ + { + "type": "WEB", + "url": "http://www.openwall.com/lists/oss-security/2024/07/31/1" + }, + { + "type": "WEB", + "url": "https://curl.se/docs/CVE-2024-7264.html" + }, + { + "type": "WEB", + "url": "https://curl.se/docs/CVE-2024-7264.json" + }, + { + "type": "FIX", + "url": "https://github.com/curl/curl/commit/27959ecce75cdb2809c0bdb3286e60e08fadb519" + }, + { + "type": "WEB", + "url": "https://hackerone.com/reports/2629968" + }, + { + "type": "ADVISORY", + "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-7264" + }, + { + "type": "ADVISORY", + "url": "https://security.netapp.com/advisory/ntap-20240828-0008/" + }, + { + "type": "ADVISORY", + "url": "https://security.netapp.com/advisory/ntap-20241025-0006/" + }, + { + "type": "ADVISORY", + "url": "https://security.netapp.com/advisory/ntap-20241025-0010/" + } + ], + "severity": [ + { + "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L", + "type": "CVSS_V3" + } + ], + "summary": "ASN.1 date parser overread" +} +--- + +[TestCVE5Snapshot/CVE-2026-20912.json - 1] +{ + "affected": [ + { + "ranges": [ + { + "database_specific": { + "extracted_events": [ { - "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" - } - ], - "source": "AFFECTED_FIELD" - }, - "events": [ - { - "introduced": "5040f7e94cd01decbe7ba8fdacbf489182d503dc" - }, - { - "last_affected": "70812c2f32fc5734bcbbe572b9f61c380433ad6a" - } - ], - "repo": "https://github.com/curl/curl", - "type": "GIT" - } - ], - "versions": [ - "7.32.0", - "7.33.0", - "7.34.0", - "7.35.0", - "7.36.0", - "7.37.0", - "7.37.1", - "7.38.0", - "7.39.0", - "7.40.0", - "7.41.0", - "7.42.0", - "7.42.1", - "7.43.0", - "7.44.0", - "7.45.0", - "7.46.0", - "7.47.0", - "7.47.1", - "7.48.0", - "7.49.0", - "7.49.1", - "7.50.0", - "7.50.1", - "7.50.2", - "7.50.3", - "7.51.0", - "7.52.0", - "7.52.1", - "7.53.0", - "7.53.1", - "7.54.0", - "7.54.1", - "7.55.0", - "7.55.1", - "7.56.0", - "7.56.1", - "7.57.0", - "7.58.0", - "7.59.0", - "7.60.0", - "7.61.0", - "7.61.1", - "7.62.0", - "7.63.0", - "7.64.0", - "7.64.1", - "7.65.0", - "7.65.1", - "7.65.2", - "7.65.3", - "7.66.0", - "7.67.0", - "7.68.0", - "7.69.0", - "7.69.1", - "7.70.0", - "7.71.0", - "7.71.1", - "7.72.0", - "7.73.0", - "7.74.0", - "7.75.0", - "7.76.0", - "7.76.1", - "7.77.0", - "7.78.0", - "7.79.0", - "7.79.1", - "7.80.0", - "7.81.0", - "7.82.0", - "7.83.0", - "7.83.1", - "7.84.0", - "7.85.0", - "7.86.0", - "7.87.0", - "7.88.0", - "7.88.1", - "8.0.0", - "8.0.1", - "8.1.0", - "8.1.1", - "8.1.2", - "8.2.0", - "8.2.1", - "8.3.0", - "8.4.0", - "8.5.0", - "8.6.0", - "8.7.0", - "8.7.1", - "8.8.0", - "8.9.0" - ] - } - ], - "database_specific": { - "cna_assigner": "curl", - "osv_generated_from": "unknown" - }, - "details": "libcurl's ASN1 parser code has the `GTime2str()` function, used for parsing an\nASN.1 Generalized Time field. If given an syntactically incorrect field, the\nparser might end up using -1 for the length of the *time fraction*, leading to\na `strlen()` getting performed on a pointer to a heap buffer area that is not\n(purposely) null terminated.\n\nThis flaw most likely leads to a crash, but can also lead to heap contents\ngetting returned to the application when\n[CURLINFO_CERTINFO](https://curl.se/libcurl/c/CURLINFO_CERTINFO.html) is used.", - "id": "CVE-2024-7264", - "modified": "2025-11-03T22:32:51.400Z", - "published": "2024-07-31T08:08:14.585Z", - "references": [ - { - "type": "WEB", - "url": "http://www.openwall.com/lists/oss-security/2024/07/31/1" - }, - { - "type": "WEB", - "url": "https://curl.se/docs/CVE-2024-7264.html" - }, - { - "type": "WEB", - "url": "https://curl.se/docs/CVE-2024-7264.json" - }, - { - "type": "FIX", - "url": "https://github.com/curl/curl/commit/27959ecce75cdb2809c0bdb3286e60e08fadb519" - }, - { - "type": "WEB", - "url": "https://hackerone.com/reports/2629968" - }, - { - "type": "ADVISORY", - "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-7264" - }, - { - "type": "ADVISORY", - "url": "https://security.netapp.com/advisory/ntap-20240828-0008/" - }, - { - "type": "ADVISORY", - "url": "https://security.netapp.com/advisory/ntap-20241025-0006/" - }, - { - "type": "ADVISORY", - "url": "https://security.netapp.com/advisory/ntap-20241025-0010/" - } - ], - "severity": [ - { - "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L", - "type": "CVSS_V3" - } - ], - "summary": "ASN.1 date parser overread" -} ---- - -[TestCVE5Snapshot/CVE-2026-20912.json - 1] -{ - "affected": [ - { - "ranges": [ - { - "database_specific": { - "extracted_events": [ - { - "introduced": "0" - }, - { - "last_affected": "1.25.3" + "range": [ + { + "introduced": "0" + }, + { + "last_affected": "1.25.3" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandardRange" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -3756,19 +4395,30 @@ "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", + "strategy": "StringRangeExpression" + }, + { + "range": [ + { + "introduced": "0" + }, + { + "fixed": "1.26.18" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StringRangeExpression" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { @@ -3853,19 +4503,30 @@ "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", + "strategy": "StandaloneSingleVersion" + }, + { + "range": [ + { + "introduced": "5.6.1" + }, + { + "last_affected": "5.6.1" + } + ], + "source": "AFFECTED_FIELD", + "strategy": "StandaloneSingleVersion" } - ], - "source": "AFFECTED_FIELD" + ] }, "events": [ { diff --git a/vulnfeeds/conversion/cve5/default_extractor.go b/vulnfeeds/conversion/cve5/default_extractor.go index c038e995469..f9053465896 100644 --- a/vulnfeeds/conversion/cve5/default_extractor.go +++ b/vulnfeeds/conversion/cve5/default_extractor.go @@ -124,9 +124,15 @@ func (d *DefaultVersionExtractor) ExtractVersions(cve models.CVE5, v *vulns.Vuln } } + references := identifyPossibleURLs(cve) + commits, err := c.ExtractCommitsFromRefs(references, httpClient, cache) + if err != nil { + metrics.AddNotef("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...) addUnresolvedRanges(unresolvedRanges) diff --git a/vulnfeeds/conversion/cve5/extraction.go b/vulnfeeds/conversion/cve5/extraction.go index c7f3b3544a3..d45f63b9b09 100644 --- a/vulnfeeds/conversion/cve5/extraction.go +++ b/vulnfeeds/conversion/cve5/extraction.go @@ -50,6 +50,7 @@ func ExtractAffectedRanges(affected models.Affected, strategyList []strategies.V prevCount := len(state.Ranges()) strategy.Extract(state, metrics) if len(state.Ranges()) > prevCount { + state.SetStrategyFrom(prevCount, strategy.Name()) metrics.AddNotef("Strategy successful: %s", strategy.Name()) } } diff --git a/vulnfeeds/conversion/cve5/strategies/cpe.go b/vulnfeeds/conversion/cve5/strategies/cpe.go index 06f28cb74dd..f17f6e80f5b 100644 --- a/vulnfeeds/conversion/cve5/strategies/cpe.go +++ b/vulnfeeds/conversion/cve5/strategies/cpe.go @@ -38,6 +38,7 @@ func extractRangeFromCPEString(cpeStr string, metrics *models.ConversionMetrics) rwms := c.ToRangeWithMetadata(vr, models.VersionSourceCPE) for i := range rwms { rwms[i].Metadata.CPE = cpeStr + rwms[i].Metadata.Strategy = "CPEVersionString" rwms[i].Metadata.Versions = []string{version} } @@ -89,6 +90,11 @@ func (s *CPEVersionStrategy) Name() string { func (s *CPEVersionStrategy) Extract(cve models.CVE5, metrics *models.ConversionMetrics) ([]models.RangeWithMetadata, error) { cpeRanges, cpeStrings, err := findCPEVersionRanges(cve, metrics) if err == nil && len(cpeRanges) > 0 { + for i := range cpeRanges { + if cpeRanges[i].Metadata.Strategy == "" { + cpeRanges[i].Metadata.Strategy = s.Name() + } + } metrics.AddNotef("Strategy successful: %s", s.Name()) metrics.VersionSources = append(metrics.VersionSources, models.VersionSourceCPE) metrics.CPEs = vulns.Unique(cpeStrings) diff --git a/vulnfeeds/conversion/cve5/strategies/strategy.go b/vulnfeeds/conversion/cve5/strategies/strategy.go index 09b4bb2d6b8..fd72f8c58b5 100644 --- a/vulnfeeds/conversion/cve5/strategies/strategy.go +++ b/vulnfeeds/conversion/cve5/strategies/strategy.go @@ -111,6 +111,15 @@ func (s *ExtractionState) Ranges() []models.RangeWithMetadata { return s.ranges } +// SetStrategyFrom assigns strategyName to the Metadata.Strategy field for all ranges starting from startIdx. +func (s *ExtractionState) SetStrategyFrom(startIdx int, strategyName string) { + for i := startIdx; i < len(s.ranges); i++ { + if s.ranges[i].Metadata.Strategy == "" { + s.ranges[i].Metadata.Strategy = strategyName + } + } +} + // VersionStrategy defines the contract for an Affected-level version extraction strategy. // Strategies are evaluated in the sequential order they appear in the configured slice. type VersionStrategy interface { diff --git a/vulnfeeds/conversion/cve5/version_extraction_test.go b/vulnfeeds/conversion/cve5/version_extraction_test.go index 1d6192899c9..a947e5552b3 100644 --- a/vulnfeeds/conversion/cve5/version_extraction_test.go +++ b/vulnfeeds/conversion/cve5/version_extraction_test.go @@ -539,7 +539,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{ @@ -548,7 +547,34 @@ func TestExtractVersions(t *testing.T) { Kind: &structpb.Value_StructValue{ StructValue: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "introduced": structpb.NewStringValue("2.0.0"), + "source": structpb.NewStringValue("AFFECTED_FIELD"), + "strategy": structpb.NewStringValue("StringRangeExpression"), + "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("2.0.0"), + }, + }, + }, + }, + { + Kind: &structpb.Value_StructValue{ + StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "fixed": structpb.NewStringValue("2.0.7"), + }, + }, + }, + }, + }, + }, + }, + }, }, }, }, @@ -557,25 +583,34 @@ func TestExtractVersions(t *testing.T) { Kind: &structpb.Value_StructValue{ StructValue: &structpb.Struct{ Fields: map[string]*structpb.Value{ - "fixed": structpb.NewStringValue("2.0.7"), - }, - }, - }, - }, - { - 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.26.18"), + "source": structpb.NewStringValue("AFFECTED_FIELD"), + "strategy": structpb.NewStringValue("StringRangeExpression"), + "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.26.18"), + }, + }, + }, + }, + }, + }, + }, + }, }, }, }, @@ -603,7 +638,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{ @@ -612,16 +646,34 @@ 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"), + "strategy": structpb.NewStringValue("StringRangeExpression"), + "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"), + }, + }, + }, + }, + }, + }, + }, + }, }, }, }, @@ -734,6 +786,54 @@ func TestExtractVersions(t *testing.T) { {Introduced: "0b3b5fdb5a058f50248cd8547824936b8dd10351"}, {LastAffected: "a381da252fe8e873c8aff22703040426cc9b2ae0"}, }, + DatabaseSpecific: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "extracted_events": { + Kind: &structpb.Value_ListValue{ + ListValue: &structpb.ListValue{ + Values: []*structpb.Value{ + { + Kind: &structpb.Value_StructValue{ + StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "source": structpb.NewStringValue("AFFECTED_FIELD"), + "strategy": structpb.NewStringValue("StandardRange"), + "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("0b3b5fdb5a058f50248cd8547824936b8dd10351"), + }, + }, + }, + }, + { + Kind: &structpb.Value_StructValue{ + StructValue: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "last_affected": structpb.NewStringValue("a381da252fe8e873c8aff22703040426cc9b2ae0"), + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, }}, }}, }, diff --git a/vulnfeeds/conversion/grouping.go b/vulnfeeds/conversion/grouping.go index 164fb7a007c..b62707210a2 100644 --- a/vulnfeeds/conversion/grouping.go +++ b/vulnfeeds/conversion/grouping.go @@ -6,6 +6,7 @@ import ( "slices" "github.com/google/osv.dev/vulnfeeds/models" + "github.com/google/osv.dev/vulnfeeds/utility" "github.com/google/osv.dev/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.AddNotef("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.AddNotef("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 4c5d9f78a63..4e58a6b3b54 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.dev/vulnfeeds/models" + "github.com/google/osv.dev/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 a4cbbb87f32..f20b386a41d 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": [ { @@ -2093,31 +2159,35 @@ ], "extracted_events": [ { - "introduced": "12.04" - }, - { - "last_affected": "12.04" - }, - { - "introduced": "14.04" - }, - { - "last_affected": "14.04" - }, - { - "introduced": "16.04" - }, - { - "last_affected": "16.04" - }, - { - "introduced": "18.04" - }, - { - "last_affected": "18.04" + "range": [ + { + "introduced": "12.04" + }, + { + "last_affected": "12.04" + }, + { + "introduced": "14.04" + }, + { + "last_affected": "14.04" + }, + { + "introduced": "16.04" + }, + { + "last_affected": "16.04" + }, + { + "introduced": "18.04" + }, + { + "last_affected": "18.04" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "canonical:ubuntu_linux" }, { @@ -2126,13 +2196,17 @@ ], "extracted_events": [ { - "introduced": "9.0" - }, - { - "last_affected": "9.0" + "range": [ + { + "introduced": "9.0" + }, + { + "last_affected": "9.0" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "debian:debian_linux" }, { @@ -2145,37 +2219,41 @@ ], "extracted_events": [ { - "introduced": "6.0" - }, - { - "last_affected": "6.0" - }, - { - "introduced": "7.0" - }, - { - "last_affected": "7.0" - }, - { - "introduced": "7.4" - }, - { - "last_affected": "7.4" - }, - { - "introduced": "7.5" - }, - { - "last_affected": "7.5" - }, - { - "introduced": "7.6" - }, - { - "last_affected": "7.6" + "range": [ + { + "introduced": "6.0" + }, + { + "last_affected": "6.0" + }, + { + "introduced": "7.0" + }, + { + "last_affected": "7.0" + }, + { + "introduced": "7.4" + }, + { + "last_affected": "7.4" + }, + { + "introduced": "7.5" + }, + { + "last_affected": "7.5" + }, + { + "introduced": "7.6" + }, + { + "last_affected": "7.6" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "redhat:enterprise_linux" } ] @@ -2251,25 +2329,29 @@ ], "extracted_events": [ { - "introduced": "36" - }, - { - "last_affected": "36" - }, - { - "introduced": "37" - }, - { - "last_affected": "37" - }, - { - "introduced": "38" - }, - { - "last_affected": "38" + "range": [ + { + "introduced": "36" + }, + { + "last_affected": "36" + }, + { + "introduced": "37" + }, + { + "last_affected": "37" + }, + { + "introduced": "38" + }, + { + "last_affected": "38" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "fedoraproject:fedora" }, { @@ -2281,31 +2363,35 @@ ], "extracted_events": [ { - "introduced": "11.5" - }, - { - "last_affected": "11.5" - }, - { - "introduced": "11.6" - }, - { - "last_affected": "11.6" - }, - { - "introduced": "12.0" - }, - { - "last_affected": "12.0" - }, - { - "introduced": "12.1" - }, - { - "last_affected": "12.1" + "range": [ + { + "introduced": "11.5" + }, + { + "last_affected": "11.5" + }, + { + "introduced": "11.6" + }, + { + "last_affected": "11.6" + }, + { + "introduced": "12.0" + }, + { + "last_affected": "12.0" + }, + { + "introduced": "12.1" + }, + { + "last_affected": "12.1" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "redhat:directory_server" } ] @@ -2429,18 +2515,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": [ @@ -2472,19 +2567,23 @@ ], "extracted_events": [ { - "introduced": "35" - }, - { - "last_affected": "35" - }, - { - "introduced": "36" - }, - { - "last_affected": "36" + "range": [ + { + "introduced": "35" + }, + { + "last_affected": "35" + }, + { + "introduced": "36" + }, + { + "last_affected": "36" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "fedoraproject:fedora" } ] @@ -2535,585 +2634,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": [ { @@ -3220,13 +3726,17 @@ ], "extracted_events": [ { - "introduced": "12.04" - }, - { - "last_affected": "12.04" + "range": [ + { + "introduced": "12.04" + }, + { + "last_affected": "12.04" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "canonical:ubuntu_linux" }, { @@ -3235,13 +3745,17 @@ ], "extracted_events": [ { - "introduced": "42.1" - }, - { - "last_affected": "42.1" + "range": [ + { + "introduced": "42.1" + }, + { + "last_affected": "42.1" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "opensuse:leap" } ] @@ -3386,16 +3900,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": [ { @@ -3419,13 +3937,17 @@ ], "extracted_events": [ { - "introduced": "40" - }, - { - "last_affected": "40" + "range": [ + { + "introduced": "40" + }, + { + "last_affected": "40" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "fedoraproject:fedora" }, { @@ -3435,19 +3957,23 @@ ], "extracted_events": [ { - "introduced": "7.0" - }, - { - "last_affected": "7.0" - }, - { - "introduced": "8.0" - }, - { - "last_affected": "8.0" + "range": [ + { + "introduced": "7.0" + }, + { + "last_affected": "7.0" + }, + { + "introduced": "8.0" + }, + { + "last_affected": "8.0" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "redhat:enterprise_linux" } ] @@ -3496,10 +4022,14 @@ ], "extracted_events": [ { - "fixed": "3.67.0" + "range": [ + { + "fixed": "3.67.0" + } + ], + "source": "CPE_RANGE" } ], - "source": "CPE_RANGE", "vendor_product": "filezilla-project:filezilla_client" }, { @@ -3508,13 +4038,17 @@ ], "extracted_events": [ { - "introduced": "0.68" - }, - { - "fixed": "0.81" + "range": [ + { + "introduced": "0.68" + }, + { + "fixed": "0.81" + } + ], + "source": "CPE_RANGE" } ], - "source": "CPE_RANGE", "vendor_product": "putty:putty" }, { @@ -3523,10 +4057,14 @@ ], "extracted_events": [ { - "fixed": "1.14.6" + "range": [ + { + "fixed": "1.14.6" + } + ], + "source": "CPE_RANGE" } ], - "source": "CPE_RANGE", "vendor_product": "tigris:tortoisesvn" }, { @@ -3535,10 +4073,14 @@ ], "extracted_events": [ { - "fixed": "2.15.0.1" + "range": [ + { + "fixed": "2.15.0.1" + } + ], + "source": "CPE_RANGE" } ], - "source": "CPE_RANGE", "vendor_product": "tortoisegit:tortoisegit" }, { @@ -3547,10 +4089,14 @@ ], "extracted_events": [ { - "fixed": "6.3.3" + "range": [ + { + "fixed": "6.3.3" + } + ], + "source": "CPE_RANGE" } ], - "source": "CPE_RANGE", "vendor_product": "winscp:winscp" }, { @@ -3561,52 +4107,60 @@ ], "extracted_events": [ { - "introduced": "38" - }, - { - "last_affected": "38" - }, - { - "introduced": "39" - }, - { - "last_affected": "39" - }, - { - "introduced": "40" - }, - { - "last_affected": "40" + "range": [ + { + "introduced": "38" + }, + { + "last_affected": "38" + }, + { + "introduced": "39" + }, + { + "last_affected": "39" + }, + { + "introduced": "40" + }, + { + "last_affected": "40" + } + ], + "source": "CPE_STRING" } ], - "source": "CPE_STRING", "vendor_product": "fedoraproject:fedora" }, { "extracted_events": [ { - "introduced": "0.68" - }, - { - "fixed": "0.80" - }, - { - "fixed": "0.81" - }, - { - "fixed": "3.67.0" - }, - { - "fixed": "6.3.3" - }, - { - "fixed": "2.15.0.1" - }, - { - "fixed": "1.14.6" + "range": [ + { + "introduced": "0.68" + }, + { + "fixed": "0.80" + }, + { + "fixed": "0.81" + }, + { + "fixed": "3.67.0" + }, + { + "fixed": "6.3.3" + }, + { + "fixed": "2.15.0.1" + }, + { + "fixed": "1.14.6" + } + ], + "source": "DESCRIPTION" } - ], - "source": "DESCRIPTION" + ] } ] }, diff --git a/vulnfeeds/conversion/versions.go b/vulnfeeds/conversion/versions.go index 3dcb099a7c1..ffcb2a75ba2 100644 --- a/vulnfeeds/conversion/versions.go +++ b/vulnfeeds/conversion/versions.go @@ -423,10 +423,10 @@ func repo(u string) (string, error) { } // Returns the commit ID from supported links. -func Commit(u string, httpClient *http.Client) (string, error) { +func Commit(u string, httpClient *http.Client) (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}") @@ -439,14 +439,14 @@ func Commit(u string, httpClient *http.Client) (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. @@ -459,14 +459,14 @@ func Commit(u string, httpClient *http.Client) (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. @@ -477,7 +477,7 @@ func Commit(u string, httpClient *http.Client) (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: @@ -489,7 +489,7 @@ func Commit(u string, httpClient *http.Client) (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 } } @@ -498,42 +498,43 @@ func Commit(u string, httpClient *http.Client) (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, httpClient) + possibleCommitHash, originalTag, err := resolveGitTag(parsedURL, u, gitSHA1Regex, httpClient) 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, httpClient *http.Client) (string, error) { +func resolveGitTag(parsedURL *url.URL, u string, gitSHA1Regex *regexp.Regexp, httpClient *http.Client) (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, httpClient) 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. @@ -560,32 +561,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, httpClient) + c, tag, source, err := Commit(link, httpClient) if err != nil { - return "", "", err + return "", "", "", models.VersionSourceNone, err } commit = c @@ -593,7 +596,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 @@ -603,7 +606,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 { @@ -1249,7 +1252,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, httpClient) + _, _, _, err = Commit(ref.URL, httpClient) // 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 a68291dc772..608d82bf326 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.dev/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, }, @@ -1129,6 +1146,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. }{ @@ -1137,40 +1156,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 { @@ -1178,7 +1202,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, r.GetDefaultClient()) + got, gotTag, gotSource, err := Commit(tt.args.u, r.GetDefaultClient()) if (err != nil) != tt.wantErr { t.Errorf("Commit() error = %v, wantErr %v", err, tt.wantErr) return @@ -1186,6 +1210,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 2d091485b17..373128ef7b2 100644 --- a/vulnfeeds/models/metrics.go +++ b/vulnfeeds/models/metrics.go @@ -131,6 +131,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..8f8c578fed8 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,11 @@ type RangeWithMetadata struct { } type Metadata struct { - CPE string - Source VersionSource - Versions []string + CPE string + Source VersionSource + Strategy string + Versions []string + OriginalTag string } func (ac *AffectedCommit) SetRepo(repo string) {