Skip to content

Commit 6117ff7

Browse files
authored
fix(vulnfeeds): prevent duplicate events in database_specific (google#5593)
`combine-to-osv` merges database_specific fields using `MergeDatabaseSpecificValues` from the `conversion` package. However, the helper function `deduplicateList` only checked comparable basic types (strings, ints, floats, bools). Non-comparable types (like maps representing JSON objects) were always appended without deduplication. I updated `deduplicateList` to check if a type is comparable. If it's not (e.g. a map or slice), it now checks for uniqueness against previously observed uncomparable elements using `reflect.DeepEqual`.
1 parent f2df998 commit 6117ff7

2 files changed

Lines changed: 41 additions & 8 deletions

File tree

vulnfeeds/conversion/common.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -434,19 +434,38 @@ func MergeDatabaseSpecificValues(val1, val2 any) (any, error) {
434434
}
435435
}
436436

437-
// deduplicateList removes duplicate comparable elements (like strings) from a list.
437+
// deduplicateList removes duplicate elements from a list.
438438
func deduplicateList(list []any) []any {
439439
var unique []any
440-
seen := make(map[any]bool)
440+
seenComparable := make(map[any]bool)
441+
var seenUncomparable []any
441442
for _, item := range list {
442-
switch item.(type) {
443-
case string, int, int32, int64, float32, float64, bool:
444-
if !seen[item] {
445-
seen[item] = true
443+
if item == nil {
444+
if !seenComparable[nil] {
445+
seenComparable[nil] = true
446+
unique = append(unique, item)
447+
}
448+
449+
continue
450+
}
451+
typ := reflect.TypeOf(item)
452+
if typ.Comparable() {
453+
if !seenComparable[item] {
454+
seenComparable[item] = true
455+
unique = append(unique, item)
456+
}
457+
} else {
458+
found := false
459+
for _, seen := range seenUncomparable {
460+
if reflect.DeepEqual(seen, item) {
461+
found = true
462+
break
463+
}
464+
}
465+
if !found {
466+
seenUncomparable = append(seenUncomparable, item)
446467
unique = append(unique, item)
447468
}
448-
default:
449-
unique = append(unique, item)
450469
}
451470
}
452471

vulnfeeds/conversion/common_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,20 @@ func TestMergeDatabaseSpecificValues(t *testing.T) {
307307
val2: 456.0,
308308
wantErr: true,
309309
},
310+
{
311+
name: "Merge lists of maps with duplicates",
312+
val1: []any{
313+
map[string]any{"introduced": "1.0"},
314+
},
315+
val2: []any{
316+
map[string]any{"introduced": "1.0"},
317+
map[string]any{"introduced": "2.0"},
318+
},
319+
want: []any{
320+
map[string]any{"introduced": "1.0"},
321+
map[string]any{"introduced": "2.0"},
322+
},
323+
},
310324
}
311325

312326
for _, tt := range tests {

0 commit comments

Comments
 (0)