Skip to content

Commit 7d30cdf

Browse files
committed
make sure utility output is deterministic
1 parent 9a2515c commit 7d30cdf

2 files changed

Lines changed: 25 additions & 12 deletions

File tree

vulnfeeds/conversion/grouping_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,8 @@ func TestMergeRangesAndCreateAffected(t *testing.T) {
463463
Introduced: "1.1",
464464
},
465465
{
466-
Repo: "repo1",
467-
Fixed: "1.2",
466+
Repo: "repo1",
467+
Fixed: "1.2",
468468
},
469469
},
470470
successfulRepos: []string{"repo1"},

vulnfeeds/utility/utility.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package utility
22

33
import (
4+
"cmp"
45
"encoding/json"
56
"fmt"
67
"reflect"
78
"regexp"
9+
"slices"
810

911
"google.golang.org/protobuf/encoding/protojson"
1012
"google.golang.org/protobuf/proto"
@@ -57,9 +59,15 @@ func IsRepoURL(url string) bool {
5759
// which is suitable for OSV's database_specific field.
5860
func NewStructpbFromMap(v map[string]any) (*structpb.Struct, error) {
5961
x := &structpb.Struct{Fields: make(map[string]*structpb.Value, len(v))}
60-
for k, v := range v {
62+
keys := make([]string, 0, len(v))
63+
for k := range v {
64+
keys = append(keys, k)
65+
}
66+
slices.Sort(keys)
67+
68+
for _, k := range keys {
6169
var err error
62-
x.Fields[k], err = newStructpbValue(v)
70+
x.Fields[k], err = newStructpbValue(v[k])
6371
if err != nil {
6472
return nil, err
6573
}
@@ -94,16 +102,21 @@ func newStructpbValue(v any) (*structpb.Value, error) {
94102
return structpbValueFromList(anyList)
95103
case reflect.Map:
96104
if val.Type().Key().Kind() == reflect.String {
97-
m := make(map[string]any)
98-
for _, k := range val.MapKeys() {
99-
m[k.String()] = val.MapIndex(k).Interface()
100-
}
101-
structpbMap, err := NewStructpbFromMap(m)
102-
if err != nil {
103-
return nil, err
105+
keys := val.MapKeys()
106+
slices.SortFunc(keys, func(a, b reflect.Value) int {
107+
return cmp.Compare(a.String(), b.String())
108+
})
109+
110+
x := &structpb.Struct{Fields: make(map[string]*structpb.Value, len(keys))}
111+
for _, k := range keys {
112+
var err error
113+
x.Fields[k.String()], err = newStructpbValue(val.MapIndex(k).Interface())
114+
if err != nil {
115+
return nil, err
116+
}
104117
}
105118

106-
return structpb.NewStructValue(structpbMap), nil
119+
return structpb.NewStructValue(x), nil
107120
}
108121

109122
return structpb.NewValue(v)

0 commit comments

Comments
 (0)